user1770094
user1770094

Reputation: 87

Class inheritance error: Private member

I've got one base class/parent class: Person

And two subclasses/child classes: Player, Coach

This is what the header for the base class Person looks like:

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

    private:
        string name;
};

I tried to compile and run, it started complaining about this:

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 ===|

And pointed to this:

private:
    string name;

In the context of one out of two constructors for the child class "Coach":

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

However, it doesn't make the same complaint about that very same line in the constructor of the "Player"-class, only complains about "string name being a private member" in the constructor of the "Coach"-class.

I looked up some solutions for other people, tried protected instead of private, tried changing the names of the variables, but to no use.

What gives?

Upvotes: 2

Views: 5860

Answers (3)

doctorlove
doctorlove

Reputation: 19232

name is private in the base class, so you can't access it from a derived class.
Assuming that Coach derives publically from Person you could make the member variable protected, but fortunately the Person constructor takes a name, so you don't need to access it from the derived classes directly. You can use the initialiser list as you are doing and therefore don't need to set it twice

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

Upvotes: 2

Pierre Fourgeaud
Pierre Fourgeaud

Reputation: 14510

A private member cannot be accessed by derived class.

The solution could be to use the member-initialization-list to do that :

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

Because Person is the base-class and have a constructor that takes a name, you can do it that way. You don't need to access the name member from the derived class.


Another solution could be to set this member protected (the first solution is still better).

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

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

You can take a look here, the inheritance part talk about access-type.


Not to answer the question but for some good practice, I would suggest you to pass your string parameter as const reference. It is a better practice :

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

Upvotes: 6

Dale Wilson
Dale Wilson

Reputation: 9434

Change "private" to "protected" private means no other part of the system, including derived classes, can access the member.

Upvotes: 0

Related Questions