我正在与一位同事讨论为什么在Visual Studio 2008中无法编译以下内容:
class base
{
protected:
virtual void f(){}
};
class a : public base
{
public:
void fa(base* pb)
{
pb->f(); // error C2248: 'base::f' : cannot access protected member declared in class 'base'
}
};
他认为这是完全合理的,但是我认为这是一个奇怪的限制,如果我希望
base
及其所有派生类成为一个封闭系统,我仍然需要将base
的某些成员公开,以便他们都可以与每个人交谈其他都是通过共享接口(interface),它们都是公开地派生的。我是否有一些用例,我没有想到允许在哪些地方访问这些 protected 成员会破坏 protected 成员的性质?
最佳答案
如果编译器允许此类操作,则可以轻松破坏封装。考虑一下:
base b;
a foo;
foo.fa(b); // we can now easily access/modify protected elements of `b`
在这种情况下,派生对象
foo
和基本b
之间没有关系,但是您可以使用派生对象来访问其“内脏”。这应该是不可能的(至少是恕我直言)。只需在
f()
中执行a.fa()
即可,因为您只修改了a
的基础部分,而不是一些无关的对象。更具体地说,您可以编写一个“包装器”,该包装器将为任何类禁用
protected
:#include <iostream>
class Base
{
public: // protected in your case, public here so it compiles
int x{42};
public:
int getx() {return x;}
};
template<typename T> // wrapper
class DisableProtected: public T
{
public:
void modify(Base* b)
{
b->x = 24;
}
};
int main()
{
Base base;
std::cout << base.getx() << std::endl;
DisableProtected<Base> foo;
foo.modify(&base); // can modify any Base
std::cout << base.getx() << std::endl;
}
关于c++ - 关于 protected 成员函数和派生类访问的困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29437724/