关于受保护的成员函数和派生类访问的混淆
Confusion regarding protected member functions and derived class access
我与一位同事讨论了为什么以下内容不能在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
的一些成员公开,这样他们就可以通过共享接口相互交谈,他们都是公开派生的。
有没有一些用例我没有想到,允许访问这些受保护的成员可能会破坏受保护成员的性质?
如果编译器允许这样做,那么您可以很容易地破坏封装。想想看:
base b;
a foo;
foo.fa(b); // we can now easily access/modify protected elements of `b`
在这种情况下,派生对象foo
和基b
之间没有关系,但是您可以使用派生来访问它的"内脏"。这应该是不可能的(至少imho)。
只需在a.fa()
中执行f()
就可以了,因为您只需修改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++继承错误
- 我可以从派生类中的静态函数访问受基类保护的成员吗
- 父类中受保护的数据在子类中不可用
- 访问父';s受保护的变量
有没有一些用例我没有想到,允许访问这些受保护的成员可能会破坏受保护成员的性质?
我认为这是为了防止一个派生类扰乱兄弟派生类的不变量。考虑
class A {
protected: void foo();
};
class B : public A {
// complicated code
};
class C : public A {
void bar(B* b) {
b->foo();
}
};
这有效地允许C
只修改B
的A
子对象,这可能违反B
对其A
子对象施加的不变量,而C
不可能知道这些不变量。
有趣的故事。我刚收到比亚恩关于这个问题的回复。以下是他的回应。
考虑
class B : public base
{
public:
// ...
};
A a;
B b;
a.f(&b); // a manipulated b's base
这导致了微妙的错误。这项工作:
class A : public base
{
public:
void fa(base* pb)
{
f(); // use your own base
}
};
相关文章:
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 按基类对象访问派生类资源时出错
- C++11: 如何访问派生类中的基类成员?
- 访问派生类的 QMetaObject
- 使用基类对象访问派生的仅类方法
- 如何在 c++ 中通过基类引用访问派生类的对象?
- 如何在 c++ 中使用多态性访问派生类字段?
- C++继承从基类指针访问派生类中的非虚拟函数
- 无法访问派生类中的基类方法
- 如果基类指针无法访问派生类成员函数,那么多态性有什么方便的呢?
- 如果我们有一个基*类,如何访问派生模板类的成员函数
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 通过在基类中虚拟调用派生类中的函数来访问派生类中的函数
- 无法访问派生类函数内的基类的受保护数据成员
- D 指针/pimpl 模式基类指针访问派生类成员
- 友元类对象是否可以在其成员函数中访问派生类对象的基类私有成员?
- 访问派生类C++中的受保护成员
- 从C++中的"interface"访问派生类成员?
- 通过基类的指针,我们无法访问派生类特定的成员
- 抽象类的需求是什么?为什么要通过其基类访问派生类方法?在C++