[英]How to access protected base class function, from derived class through base class ptr
我有抽象类A,从中继承了许多类。 在派生类中,我试图在A槽A指针中访问受保护的函数。 但是我得到一个编译器错误。
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
D(A* aa) :mAPtr(aa){}
void g();
protected:
virtual void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
void D::f(){ }
void D::g()
{
mAPtr->f();
}
编译器错误说:无法访问在类A中声明的受保护成员A :: f。
如果我将mAPtr声明为D *,则A *一切都会编译。 我不明白为什么会这样。
依靠private
访问对相同类型的不相关实例起作用。
依赖protected
访问可用于相同类型(以及更多派生类型)的不相关实例。
然而,依赖于protected
访问不会在基类的实例无关的工作。
[n3290: 11.5/1]:
当 派生类 的朋友或成员函数引用 基类 的受保护的非静态成员函数或受保护的非静态数据成员时 ,除了第11节中所述的访问检查之外,还将进行访问检查。当形成指向成员(5.3.1)的指针时, 访问必须通过指向,引用或引用派生类本身(或从该类派生的任何类) (5.2.5)的对象的对象来实现 。 如果访问要形成指向成员的指针,则嵌套名称说明符应命名派生类(或从该类派生的任何类)。
所以D
或从D
衍生而来的东西,而不是A
尽管如此,关于C ++的一种经常被质疑的怪异之处仍然是旨在避免陷阱。 毕竟,您不知道*mAPtr
真正具有什么类型。
包含受保护节的类意味着该类允许派生类以其选择的任何方式(在受保护的接口允许的范围内)操纵其基类。
D类对象可以操纵自己的A部分。 这样说来,他们可能想要保持一些不变性。
假设存在(或将来还会有!)另一个类E,它也继承自A。类E对象也可以操纵自己的A部分,并且它们可以强制执行不同的不变式。
现在,如果允许D类对象操作任何对象的A部分,则不能确保不变性。 AD对象可能会对E对象的A部分造成破坏,从而破坏该E对象。 这就是为什么不允许这样做。
但是,如果您确实愿意,也许可以通过一个朋友函数来调用A :: f而不暴露给所有人。
class A;
namespace detail
{
void call_f(A*);
}
class A
{
friend void detail::call_f(A*);
private:
virtual void f() = 0;
};
namespace detail
{
void call_f(A* a) { a->f(); }
}
class D: public A
{
public:
void g() { detail::call_f(mAPtr); }
private:
void f() {}
A* mAPtr;
};
这依赖于对用户进行严格训练,以使其不进入名称空间,该名称空间清楚地表明其包含实现细节。
您忘记了使用;
课后声明:
class A
{
protected:
virtual void f()=0;
};
class D : public A
{
public:
void g();
protected:
void f();
private:
A* mAPtr; // ptr shows to some derived class instance
};
此外,您不需要存储基类指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.