为什么我的对象无法访问在公共基类中定义的另一个对象的受保护成员?

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

本文关键字:定义 一个对象 成员 受保护 基类 对象 我的 访问 为什么      更新时间:2023-10-16

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

"BaseTest::_protMember":无法访问中声明的受保护成员类"BaseTest"

为什么我不能访问class SubTest中的成员变量_protMember,即使它受到保护?

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

后续问题:

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

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

换句话说,您的SubTest可能会决定使用与另一个BaseTest派生类(比如SubTest2 : BaseTest)对同一成员的使用冲突的protected成员。如果您的SubTest代码被允许篡改其他对象的数据,它可能会使SubTest2对象中的不变量无效,或者获取一些值,这些值在预期的封装中仅用于暴露于SubTest2和(可选地,见下文)SubTest2导数。

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

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

上面同样的见解解释了为什么允许这样做:复制构造函数获得SubTest&,而不仅仅是从BaseTest派生的任何旧对象,而且这个构造函数显然在SubTest抽象中。假定SubTest编码器熟悉SubTest所提供的预期设计/封装,并且拷贝构造函数也被授予绕过并在另一个SubTest&对象上强制执行后置条件/不变量的权限。(您正在从一个对象复制,该对象本身可能是由相同的函数复制构建的,因此在"*this"侧而不是在ref侧保护它根本没有多大保护作用,甚至忽略了您可能想要/需要该访问的所有合理原因)。

CCD_ 20派生的对象可能会意外地传递给CCD_ 21复制构造函数("切片"),但即使在这种情况下,SubTest&类也可以控制进一步派生的对象是否会对_protMember做任何意外的事情——如果它想"最终确定"对_protMember的访问并禁止任何派生类使用它,则添加private using BaseTest::_protMember;语句

只能在类实例中访问protected成员。即:

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

编辑后续内容:

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

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

这是我的来源:为什么我可以访问复制构造函数中的私有变量?

通过将_protMember定义为protected,允许派生类的对象访问它们自己的_protMember。这并不意味着派生类的所有对象都可以访问其他对象的_protMember