Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

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

The following code produces a compiler error:

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

Why can't I access the member variable _protMember in my class SubTest even though 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
    };
};

Followup question:

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...