繁体   English   中英

如何从派生类到基类ptr访问受保护的基类函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM