Protected Data Members?

I'm a little confused about protected class members.
I know that a protected member can only be accessed within the class it was declared and withing classes derived from that class.

What I can't understand is why the below doesn't work. If I want to access the class member directly I'm not sure why I can't write a::protected_member as per below.

eg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;


class a
{
protected:
int protected_member;
};

void myfunction()
{
a::protected_member = 5;  // I am not sure why I can't access the class variable directly like            //this when it is protected?
cout << a::protected_member  << endl;
}

int main()
{
myfunction();
}
Last edited on
void myfunction() is not a member or friend of a

A protected member of a class Base can only be accessed
1) by the members and friends of Base
2) by the members and friends of any class derived from Base, but only when operating on an object of a type that is derived from Base (including this)
http://en.cppreference.com/w/cpp/language/access
JLBorges is correct.
What's more, protected_member must belong to a object. Only if protected_member is a static variable, it can be accessed like this a::protected_member.
Thanks both.. So just to confirm. If I am going to access protected_member I can only do so within the definition of class a? And... there is no way of accessing that member (if not static) outside of the class definition if I am not declaring a new instance of class a?

The reason I ask is this.. Please see the example below. I'm not sure why this happens but if I derive a class from a class containing the protected member I can only seem to use it if it is used inside a member function within the derived class. Am I missing a fundamental point with this?

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
#include <iostream>
using namespace std;


class a
{
protected:
int protected_member;
};

class b
{
public:

//if I initialize the protected member here then I get an error as 
//protected_member is not recognized. 
//eg.
protected_member = 7;

int myfunction()
{
protected_member = 6; // if I initialize the protected_member here the code works fine
cout << protected_member;
}

};


int main()
{
b myobject;
myobject.myfunction();

}
Last edited on
> If I am going to access protected_member I can only do so within the definition of class a?

No. The access does not have to be within the definition of class a.

But it has to be from a member or friend of a.
Or from a member or friend of a derived class of a (access the inherited protected member in the derived class).

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
struct a
{
    void member_of_a() ;

    protected: int protected_member = 0 ;

    friend void foo( a& object ) ;
};

void a::member_of_a() { ++protected_member ; } // fine: member of a

void foo( a& object ) { ++object.protected_member ; } // fine: friend of a

struct b : a
{
    void member_of_b() ;

    friend void bar( b& object ) ;
};

void b::member_of_b() { ++protected_member ; } // fine: member of b can access inherited protected member in b

void bar( b& object ) { ++object.protected_member ; } // fine: friend of b can access inherited protected member in b

struct e ;

struct c : b
{
    friend void baz( c& object ) ;
    friend void baz( b& object ) ;
    friend void baz( e& object ) ;
    
    struct d 
    { 
        static void member_of_d( c& object );
        static void member_of_d( b& object );
    };
};

struct e : c {};

void baz( c& object ) { ++object.protected_member ; } // fine: friend of c can access inherited protected member in c

// void baz( b& object ) { ++object.protected_member ; } // *** error: can't access inherited protected member of a in b

void baz( e& object ) { ++object.protected_member ; } // fine: friend of c can access inherited protected member in c (e is derived from c)

void c::d::member_of_d( c& object ) { ++object.protected_member ; } // fine: member of member of c can access inherited protected member in c

// void c::d::member_of_d( b& object ) { ++object.protected_member ; } // *** error: can't access inherited protected member of a in b

int main()
{
    a a ; a.member_of_a() ; foo(a) ;

    c b ; b.member_of_b() ; bar(b) ;

    c c ; c::d::member_of_d(c) ;
}

http://coliru.stacked-crooked.com/a/d989d71d71f8bc5b
Thanks but your answer is rather confusing.
I understand that protected members can be accessed by the base and derived class but in my last example above I can't work out why the protected member of the base class can only be seen from within a function definition of the derived class used in my example?
Dominover, in you last example, both of the protected_member And you will get an error on both of them. Try and remove the one outside the function, compile and you'll see.

Protected shit can only be access within the class itself, or from classes that inherets from it, its literally that simple.

Edit: And like JLBorges said in his first post.

void myfunction() has nothing to do with class aso why should you be able to access it?
Last edited on
Quite honestly, I have seen many reasons to pretend that "protected" doesn't exist, and none to actually use it.

Further, a derived class is a cheat, basically it is a copy of a base class with some added elements. Thus of you make an object of class b, but not class a, then there is no object a to affect, only members of b (which includes copies of what is in a.)

So class b is actually it's own class, it includes everything listed for it, plus everything listed for a.

Thus, you tried to create two of the same thing in b, one that got inherited, the other you tried to explicitly add.

Try initialization in the constructor instead.
I see what you're both saying but I have provided both uses of the protected members on line 18 and 22. When compiling I only use one.

If you comment out line 18 ("protected_member = 7;") with my MinGW compiler the program compiles fine. But if you comment out line 22 and keep line 18 I get an error. They both show the same thing but line 22 is inside a function?

I have provided ample comments in that example to explain the issue. Thanks for coming back.. I'm thinking this could be a more to do with a MinGW compiler.

I have provided the same code below.


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
#include <iostream>
using namespace std;


class a
{
protected:
int protected_member;
};

class b
{
public:

//if I initialize the protected member here then I get an error as 
//protected_member is not recognized. 
//eg.
protected_member = 7;

int myfunction()
{
protected_member = 6; // if I initialize the protected_member here the code works fine
cout << protected_member;
}

};


int main()
{
b myobject;
myobject.myfunction();

}




Last edited on
> I can't work out why the protected member of the base class can only be seen
> from within a function definition of the derived class used in my example

To let the derived class author have a say in how the protected member is initialised:

a. Write a constructor for the base class which initialises the protected member with the argument passed to it.
(This may be a protected constructor).
1
2
3
4
5
6
struct a
{
    / * protected: */ explicit a( int v = 0 ) : protected_member(v) {}

    protected: int protected_member = 0 ;
};


b. In the derived class, write a constructor with a member-initializer-list to initialise the base class sub-object.
1
2
3
4
struct b : a
{
    b() : a(7) {} // initialise base class sub-object with 7
};
Dominover, think of it this way, When does line 18 get run? Answer, never. There is no point in which the program control goes into the general definition of a class, only into functions of that class. Thus you can't take an existing variable and initialize it somewhere the program control never reaches.
Thanks for the explanations. I think I've got it now.
Topic archived. No new replies allowed.