C++ 为什么可以';我的对象访问是否受公共基类中定义的另一个对象的保护成员?

C++ 为什么可以';我的对象访问是否受公共基类中定义的另一个对象的保护成员?,c++,C++,以下代码生成编译器错误: “BaseTest::_protember”:无法访问在中声明的受保护成员 类“BaseTest” 为什么我不能访问我的类子测试中的成员变量\u protember,即使它受到保护 class BaseTest { public: BaseTest(){}; BaseTest(int prot) { _protMember = prot; }; protected: int _protMember; }; c

以下代码生成编译器错误:

“BaseTest::_protember”:无法访问在中声明的受保护成员 类“BaseTest”

为什么我不能访问我的
类子测试
中的成员变量
\u protember
,即使它受到保护

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
    };
};

后续问题:


为什么在添加的复制构造函数中,我可以访问另一个实例的受保护成员?

您只能从自己的基类实例访问受保护的成员。。。没有一个作为参数提供给您。实际上,这都是关于OO封装的。如果没有此限制,正在构造的对象可能会使
baseTest&
参数的不变量无效

换句话说,您的
子测试
可能决定对受
保护的
成员的使用,该成员的使用与另一个
BaseTest
派生类对同一成员的使用冲突(例如
SubTest2:BaseTest
)。如果允许
子测试
代码篡改其他对象的数据,则可能会使
子测试2
对象中的不变量无效,或者获取一些值,这些值在预期的封装中仅用于暴露于
子测试2
和(可选-请参见下文)
子测试2
派生

跟进问题: 为什么在添加的复制构造函数中我可以访问另一个实例的受保护成员

上面相同的见解解释了为什么允许这样做:复制构造函数获得一个
子测试&
,而不仅仅是从
BaseTest
派生的任何旧对象,而且该构造函数显然在
子测试
抽象中。假设
子测试
编码者熟悉
子测试
提供的预期设计/封装,复制构造函数也可以绕过并在另一个
子测试&
对象上强制post条件/不变量。(您正在从一个对象进行复制,而该对象本身可能是由同一个函数复制构造的,因此在“
*this
”侧保护它而不是ref侧的参数并没有多大的保护作用,甚至忽略了您可能希望/需要该访问的所有合理原因)


子测试
派生的对象可能会意外地传递给
子测试
复制构造函数(“切片”),但是,即使在这种情况下,
子测试&
类也可以控制进一步派生的对象是否在
\u protemember
-使用BaseTest::\u protemember添加一个
私有的
\u protemember
并禁止任何派生类使用它,则使用code>语句。

通过将
\u protemember
定义为
受保护的
,可以允许派生类的对象访问其自己的
\u protemember
。这并不意味着派生类的所有对象都可以访问其他对象的
\u protember

您只能在类实例中访问
受保护的
成员。即:

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.
    };
};
编辑后续内容:

访问修饰符在类级别工作,而不是在对象级别工作

也就是说,同一类的两个对象可以访问彼此的私有成员


这是我的来源:

谢谢你的回答。你能看一下我添加的后续问题吗(使用一个可以访问另一个实例的受保护成员的函数)。@RonaldMcBean:我在回答中添加了这个问题。(“可以访问另一个实例的受保护成员的函数”-但不是
BaseTest
-但不是-
子测试
-派生实例-这是问题的症结所在)这是一个很好的答案。几年前我遇到过这个问题,我花了很长时间才知道编译器为什么这样做。我意识到C++的设计者在理解对象的职责方面的细微之处做了很大的工作。谢谢你的回答。你能看看F吗?下面是我编辑的问题?请看代码的第5行-它不是应该是
子测试吗?@Shumail92实际上不是,当我第一次发布它时,测试只是用baseTest:)我将编辑我的帖子。
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.
    };
};