Why can't my object access protected members of another object defined in common base class?

后端 未结 3 692
鱼传尺愫
鱼传尺愫 2020-12-06 19:00

The following code produces a compiler error:

\'BaseTest::_protMember\' : cannot access protected member declared in class \'BaseTest\'

相关标签:
3条回答
  • 2020-12-06 19:06

    You can only access protected members from your own base class instance... not one provided to you as a parameter. It's all about OO encapsulation really. Without this restriction, the object under construction could invalidate invariants of the baseTest& parameter.

    Put another way, your SubTest may decide on a use for a protected member that conflicts with the usage made of the same member by another BaseTest-derived class (say SubTest2 : BaseTest). If your SubTest code was allowed to fiddle with the other object's data, it could invalidate the invariants in a SubTest2 object, or get some values out that were - in the intended encapsulation - only meant to be exposed to SubTest2 and (optionally - see below) SubTest2 derivatives.

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

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

    The same insights above explain why this is allowed: the copy constructor gets a SubTest& rather than just any old object derived from BaseTest, and this constructor is clearly within the SubTest abstraction. The SubTest coder is assumed to be conversant with the intended design/encapsulation SubTest provides, and the copy constructor is given access to bypass and enforce post-conditions/invariants on the other SubTest& object too. (You are copying from an object that might itself have been copy-constructed by the very same function, so protecting it when on the "*this" side but not the parameter-by-ref side isn't much protection at all, even ignoring all the sound reasons you may want/need that access).

    It is possible that a SubTest-derived object will be accidentally passed to the SubTest copy constructor ("slicing"), but even for that scenario the SubTest& class can control whether the further-derived object could have been doing anything unexpected with _protMember - adding a private using BaseTest::_protMember; statement if it wants to "finalise" access to _protMember and forbid any derived classes from using it.

    0 讨论(0)
  • 2020-12-06 19:08

    You can access protected members only in the class instance. That is :

    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 the followup :

    The access modifiers work on class level, and not on object level.

    That is, two objects of the same class can access each others private members.

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

    0 讨论(0)
  • 2020-12-06 19:33

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

    0 讨论(0)
提交回复
热议问题