Why can't my object protect the protected members of another object defined in the base class?

The following code generates a compiler error:

'BaseTest :: _ protMember': cannot access the protected member declared in class 'BaseTest'

Why can't I access the _protMember member _protMember in my class SubTest even if it is protected?

 class BaseTest { public: BaseTest(){}; BaseTest(int prot) { _protMember = prot; }; protected: int _protMember; }; class SubTest : public BaseTest { // followup question SubTest(const SubTest &subTest) { _protMember = subTest._protMember; // this line compiles without error }; SubTest(const BaseTest &baseTest) { _protMember = baseTest._protMember; // this line produces the error }; }; 

Follow up question:

Why is it that in the added copy constructor I can access the protected members of another instance?

+7
c ++
source share
3 answers

You can only access protected members from your own instance of the base class ... none of them are provided to you as a parameter. It's all about encapsulating OO. Without this restriction, an object under construction can invalidate the invariants of the baseTest& parameter.

In other words, your SubTest may decide to use for a protected member that conflicts with using the same member with another BaseTest -derived class (say SubTest2 : BaseTest ). If your SubTest code SubTest allowed to play with other object data, this can invalidate the invariants in the SubTest2 object or get some values ​​that were - in the intended encapsulation - only to be exposed to SubTest2 and (optionally, see below) SubTest2 derivatives.

Follow-up question: Why is it that in the added copy constructor I can access the protected members of another instance?

 SubTest(const SubTest& x); // can access x._protMember SubTest(const BaseTest& x); // cannot access x._protMember 

The same thing described above explains why this is allowed: the copy constructor gets SubTest& , and not just any old object obtained from BaseTest , and this constructor is explicitly in the SubTest abstraction. It is assumed that the SubTest encoder is familiar with the intended construction / encapsulation of SubTest , and the copy constructor is granted access to bypass and enforce post-conditions / invariants on another SubTest& object. (You are copying an object, which itself can be replicated by the same function, so protecting it, if on the *this side, but not on the parameter side, is not significant protection, even ignoring all the reasons why you may need / need this access).

It is possible that a SubTest -adjusted object will be accidentally passed to the SubTest copy SubTest ("cut"), but even for this scenario, the SubTest& class can control whether the object can be done unexpectedly with _protMember - by adding a private statement using BaseTest::_protMember; if he wants to "finalize" access to _protMember and prohibit the use of any derived classes.

+10
source share

You can access protected members only in an instance of the class. I.e:

 class SubTest : public BaseTest { SubTest(const BaseTest &baseTest) { _protMember = baseTest._protMember; // ^^^^^^^^^^^ Is good because you are in the instance of its class _protMember = baseTest._protMember; // ^^^^^^^^^^^^^^^^^^^^^ Produce error because you are not in the baseTest instance. }; // followup question SubTest(const SubTest &subTest) { _protMember = subTest._protMember; // Compile because access modifiers work on class level, and not on object level. }; }; 

EDIT for follow up:

Access modifiers work at the class level, not at the object level.

That is, two objects of the same class can access each other's private members.

This is my source: Why can I access private variables in the copy constructor?

+5
source share

_protMember defining _protMember as protected , you allow objects of derived classes to access their _protMember . This does not mean that all objects of derived classes can access _protMember other objects.

0
source share

All Articles