Reputation: 87
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
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
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
Reputation: 9434
Change "private" to "protected" private means no other part of the system, including derived classes, can access the member.
Upvotes: 0