Can a derived class access protected variables of the base class?

A really horrible example off the top of my head (I know I wouldn't use this analogy for a class usually):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Base
{
    public:
        Base(int a, string b) : Score(a), Name(b) {}
        ~Base();
        void SetScore(int Points) const { Score += Points; }
        int GetScore() { return Score; }
        string GetName() { return Name; }
    protected:
        int Score;
        string Name;
};

class Child : public Base
{
    public:
        Child(int a, string b) : Score(a), Name(b) {}
        ~Child();
        void SetWinner(bool Answer) const { Winner = Answer; }
        bool GetWinner() { return Winner; }
};

int main()
{
    Base Thing(0, "Guy");
    cout << Thing.GetName() << ' ' << Thing.GetScore();
    
    Child Thing2(20, "Gus"); // <--- Can I do this!
    cout << Thing2.GetName() << ' ' << Thing2.GetScore();
    
    Thing2.SetWinner(true);
    cout << "\n\n" << Thing2.GetName() << " beats " << Thing.GetName() << "!\n\n";
    
    return 0;    
}


Basically I know that I can use the Base class's functions and I can overload them if I make them virtual, but in my program when I try to use protected variables in the Base class in my derived class's constructor, it says that those variables aren't in the derived class. Like:

class 'Child' does not have any field named' Score'.
Have you read this sites tutorial?
Yes I did, as well as others in books. I just haven't been programming in a while because I haven't had a laptop, so I'm a little rusty.
It's just that you cannot list the base class members in the constructor initialization list. Instead you can use the base class constructor
Child(int a, string b) : Base(a, b) {}
I do not see where is identifier Winner defined?!

If a derievd class inherites a base class with access specifier public it may access protected members of the base class.

If a derievd class uses the same constructors as the base class it can inherites base class constructors.

For example instead of

1
2
3
4
5
6
class Child : public Base
{
    public:
        Child(int a, string b) : Score(a), Name(b) {}
...
};


you can write

1
2
3
4
5
6
class Child : public Base
{
    public:
    using Base::Base;
...
};


Last edited on
A class can only initialize its own members in its initializer list. Score and Name are not members of Child, they are members of Base.

The best way to do this is to call the appropriate Base constructor from Child's initializer list:

1
2
3
//Child(int a, string b) : Score(a), Name(b) {}  // bad

Child(int a, string b) : Base(a,b) { } // good 




EDIT: Anyway, the answer to your topical question is "yes". Derived classes can access protected base class members... just not in the initializer list.
Last edited on
Huh, that seems like strange syntax and I've never come across it before. It works though, so thanks for the help guys. I thought I was going insane, but I just haven't used the variables anywhere other than in the initializer list, so..
Topic archived. No new replies allowed.