访问另一个子类中基类的受保护成员

2021-12-17 00:00:00 inheritance encapsulation protected c++

为什么要编译:

class FooBase
{
protected:
    void fooBase(void);
};

class Foo : public FooBase
{
public:
    void foo(Foo& fooBar)
    {
        fooBar.fooBase();
    }
};

但这不是吗?

class FooBase
{
protected:
    void fooBase(void);
};

class Foo : public FooBase
{
public:
    void foo(FooBase& fooBar)
    {
        fooBar.fooBase();
    }
};

一方面,C++ 授予对该类的所有实例的私有/受保护成员的访问权限,但另一方面,它不授予对子类的所有实例的基类的受保护成员的访问权限.这在我看来相当不一致.

On the one hand C++ grants access to private/protected members for all instances of that class, but on the other hand it does not grant access to protected members of a base class for all instances of a subclass. This looks rather inconsistent to me.

我已经测试了使用 VC++ 和 ideone.com 进行编译,并且都编译了第一个代码片段,但没有编译第二个代码片段.

I have tested compiling with VC++ and with ideone.com and both compile the first but not the second code snippet.

推荐答案

foo 收到一个 FooBase 引用时,编译器不知道该参数是否是后代Foo,所以它必须假设它不是.Foo 可以访问其他Foo 对象的继承保护成员,而不是所有其他同级类.

When foo receives a FooBase reference, the compiler doesn't know whether the argument is a descendant of Foo, so it has to assume it's not. Foo has access to inherited protected members of other Foo objects, not all other sibling classes.

考虑这个代码:

class FooSibling: public FooBase { };

FooSibling sib;
Foo f;
f.foo(sib); // calls sib.fooBase()!?

如果Foo::foo可以调用任意FooBase后代的protected成员,那么它就可以调用FooSibling的protected方法,它有与 Foo 没有直接关系.这不是受保护访问的工作方式.

If Foo::foo can call protected members of arbitrary FooBase descendants, then it can call the protected method of FooSibling, which has no direct relationship to Foo. That's not how protected access is supposed to work.

如果 Foo 需要访问所有 FooBase 对象的受保护成员,而不仅仅是那些也已知是 Foo 后代的成员,那么 Foo 需要是 FooBase 的朋友:

If Foo needs access to protected members of all FooBase objects, not just those that are also known to be Foo descendants, then Foo needs to be a friend of FooBase:

class FooBase
{
protected:
  void fooBase(void);
  friend class Foo;
};

相关文章