2013-08-27 43 views
1

我有一个基类/父类:人类继承错误:个人会员

和两个子类/子类:球员,教练

这是基类人看起来头像:

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    private: 
     string name; 
}; 

我试图编译和运行,它开始抱怨这一点:

include\Person.h||In constructor 'Coach::Coach(std::string, std::string)':| 
include\Person.h|19|error: 'std::string Person::name' is private| 
\src\Coach.cpp|5|error: within this context| 
||=== Build finished: 2 errors, 0 warnings ===| 

,并指出这一点:

private: 
    string name; 

进一出的两个构造子类“教练”的背景:

Coach::Coach(string name, string responsibility): Person(name){ 
    this->name = name; 
    this->responsibility = responsibility; 
} 

但是,它并没有对此做出了同样的抱怨非常“Player”类构造函数中的相同行,只在“Coach”类的构造函数中声明“字符串名称是私有成员”。

我查了一些其他人的解决方案,试图保护而不是私人,试图改变变量的名称,但没有用。

什么给?

+1

如果您已经在Coach构造函数中调用Person(name),为什么需要设置this-> name在所有?我认为Person :: Person会照顾那个吗? 在任何情况下,受保护的范围都应该起作用。 – Vivek

+0

获取一本[关于C++的正派书籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 'Player :: name'是私人的。如果你希望派生类具有成员级访问权(在这种情况下没有理由,但多数民众赞成在另一个问题)它需要*保护*或*公共*或*朋友* -ed(后者非常不寻常的派生类)。 – WhozCraig

+0

你如何申报Coach课程? (不要忘记在那里使用公开的词) – doctorlove

回答

4

A private成员不能被派生类访问。

的解决方案是使用成员初始化列表做到这一点:

Coach::Coach(string name, string responsibility): Person(name){ 
    //           ^^^^^^^^^^^^ 
    //      Initialize the name through the base class constructor 
    this->responsibility = responsibility; 
} 

因为Person基类,并有一个构造函数的名称,你可以做就这样。您无需访问派生类中的name成员。


另一种解决方案可以是设置这个构件protected第一溶液仍然是较好)。

class Person 
{ 
    public: 
     Person(string name); 
     Person(); 
     virtual ~Person(); 
     string getName(); 
     void setName(string name); 
     virtual void printSpec() const = 0; 

    protected: 
// ^^^^^^^^^ 
     string name; 
}; 

你可以看看here,继承部分讲的是access-type。


不回答这个问题,但一些好的做法,我建议你到你string传递参数作为参考const。这是一个better practice

Coach::Coach(const string& name, const string& responsibility): Person(name){ 
    //  ^^^^^  ^  ^^^^^  ^
    this->responsibility = responsibility; 
} 
+0

'Coach' ** **是从'Person'派生的,所以构造函数是正确的方法。将'name'更改为** protected ** ** **。构造函数可以初始化成员,如果需要,可以使用'setName'成员函数稍后进行设置。 –

+0

@PeteBecker你是对的,我编辑我的帖子,使其更合适。感谢您指出了这一点。 –

1

将“私有”更改为“受保护”私有意味着系统的其他部分(包括派生类)不能访问该成员。

+0

**不要**将其更改为受保护。 Person的构造函数初始化'name','setName'成员函数根据需要更改它。这里没有理由使用'protected'。 –

+0

同意。我只是解决了“为什么编译器会产生错误”。使用访问器方法比保护更好(在这种情况下)。 –

2

name是在基类私有的,所以你不能从派生类访问它。
假设Coach从Person公开派生出来,您可以使该成员变量受到保护,但幸运的是,构造函数接受一个名称,所以您不需要直接从派生类访问它。您可以使用初始化列表,因此不需要设置两次

Coach::Coach(string name, string responsibility) 
        : Person(name){ 
       // ^^^^^^^^^^^^ 
       // Sends name to Person's constructor 
    this->responsibility = responsibility; 
} 
+0

'教练'不需要公开派生**;只要'Person'是一个基类,它就可以在初始化程序列表中初始化。 –

+0

真的很抱歉,我会编辑我失去的想法 – doctorlove