简体   繁体   English

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

[英]How to access protected base class function, from derived class through base class ptr

I have abstract class A, from which I inherit a number of classes. 我有抽象类A,从中继承了许多类。 In the derived classes I am trying to access protected function in A trough A pointer. 在派生类中,我试图在A槽A指针中访问受保护的函数。 But I get a compiler error. 但是我得到一个编译器错误。

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();
}

The compiler error says : cannot access protected member A::f declared in class A. 编译器错误说:无法访问在类A中声明的受保护成员A :: f。

If I declare mAPtr to be D*, instead A* everything compiles. 如果我将mAPtr声明为D *,则A *一切都会编译。 And I don't understand why is this. 我不明白为什么会这样。

Relying on private access works on unrelated instances of the same type. 依靠private访问对相同类型的不相关实例起作用。

Relying on protected access works on unrelated instances of the same type (and of more derived types). 依赖protected访问可用于相同类型(以及更多派生类型)的不相关实例。

However, relying on protected access does not work on unrelated instances of a base type. 然而,依赖于protected访问不会在基类的实例无关的工作。

[n3290: 11.5/1]: When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class , an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). [n3290: 11.5/1]: 派生类 朋友或成员函数引用 基类 的受保护的非静态成员函数或受保护的非静态数据成员 ,除了第11节中所述的访问检查之外,还将进行访问检查。当形成指向成员(5.3.1)的指针时, 访问必须通过指向,引用或引用派生类本身(或从该类派生的任何类) (5.2.5)的对象的对象来实现 If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class). 如果访问要形成指向成员的指针,则嵌套名称说明符应命名派生类(或从该类派生的任何类)。

So D or something derived from D , but not A . 所以D或从D衍生而来的东西,而不是A

It's an oft-questioned cute oddity about C++ that nonetheless is designed to try to avoid pitfalls. 尽管如此,关于C ++的一种经常被质疑的怪异之处仍然是旨在避免陷阱。 After all, you don't know what type *mAPtr really has. 毕竟,您不知道*mAPtr 真正具有什么类型。

A class containing a protected section means that this class allows derived classes to manipulate their base class in any way they choose (as far as the protected interface allows). 包含受保护节的类意味着该类允许派生类以其选择的任何方式(在受保护的接口允许的范围内)操纵其基类。

Class D objects can manipulate their own A part. D类对象可以操纵自己的A部分。 In doing say they probably want to maintain some invariants. 这样说来,他们可能想要保持一些不变性。

Suppose there is (or will be in the future!) another class E, also inherited from A. Class E objects also can manipulate their own A part, and they may be enforcing different invariants. 假设存在(或将来还会有!)另一个类E,它也继承自A。类E对象也可以操纵自己的A部分,并且它们可以强制执行不同的不变式。

Now, if a class D object was allowed to manipulate the A part of any object, it can't ensure the invariants. 现在,如果允许D类对象操作任何对象的A部分,则不能确保不变性。 AD object may do something to the A part of an E object that breaks that E object. AD对象可能会对E对象的A部分造成破坏,从而破坏该E对象。 That's why it is not allowed. 这就是为什么不允许这样做。


But if you really want to, perhaps a way to call A::f, without exposing it to everybody, would be via a friend function. 但是,如果您确实愿意,也许可以通过一个朋友函数来调用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;
};

This relies on users being disciplined enough to stay out of namespaces whose name clearly indicates that it contains implementation details. 这依赖于对用户进行严格训练,以使其不进入名称空间,该名称空间清楚地表明其包含实现细节。

You forgot using ; 您忘记了使用; after class declaration: 课后声明:

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
};

Besides, you don't need to store base class pointer. 此外,您不需要存储基类指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从派生类访问基类中的受保护方法? - How to access protected method in base class from derived class? 从派生类访问基类受保护的嵌套类 - access base class protected nested class from derived class 从派生类访问基类函数 - Access base class function from derived class 从派生类访问基类的受保护数据成员 - Access protected data members of the base class from the derived class 无法从派生类访问基类中的受保护成员 - Can't access protected member in base class from derived class 使用派生类的朋友提供的基类的受保护静态函数 - Use protected static function of the base class from the friend of the derived class 基类的好友类如何通过从基类派生的类的对象访问该基类的成员? - How does friend class of the base class access members of that base class through objects of class derived from the base class? C ++如何通过派生类的实例访问受保护的基类方法 - C++ how to access a protected base class method through an instance of the derived class 为什么派生类不能通过指向基类的指针访问其基类的受保护成员? - Why can a derived class not access a protected member of its base class through a pointer to base? 通过对基类的虚拟调用来访问派生类中的函数 - Access a function in derived class through virtual call to it in base class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM