2

我有一个基类/父类:Person

以及两个子类/子类:Player、Coach

这是基类 Person 的标头的样子:

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::Coach(string name, string responsibility): Person(name){
    this->name = name;
    this->responsibility = responsibility;
}

但是,它并没有对“Player”类的构造函数中的同一行提出同样的抱怨,只是抱怨“Coach”类的构造函数中的“字符串名称是私有成员”。

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

是什么赋予了?

4

3 回答 3

6

派生类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;
};

可以看这里,继承部分讲的是access-type。


不是为了回答这个问题,而是为了一些好的做法,我建议您将string参数作为const参考传递。这是一个更好的做法

Coach::Coach(const string& name, const string& responsibility): Person(name){
    //       ^^^^^       ^       ^^^^^       ^
    this->responsibility = responsibility;
}
于 2013-08-27T15:36:32.543 回答
2

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

Coach::Coach(string name, string responsibility)
                   : Person(name){
                 //  ^^^^^^^^^^^^
                 // Sends name to Person's constructor
    this->responsibility = responsibility;
}
于 2013-08-27T15:38:42.307 回答
1

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

于 2013-08-27T15:36:21.670 回答