为什么不可能获得指向基类的受保护方法的指针?

时间:2014-07-25 10:33:13

标签: c++ inheritance

class A {
public:
   A() {auto tmp = &A::foo;}
protected:
   void foo() {}
};

class B : public A {
public:
   B() {auto tmp = &A::foo;}
};

A编译没问题。类B产生编译错误:

  

' A :: foo的' :无法访问在类' A'

中声明的受保护成员

为什么这样,理由是什么?有没有办法绕过这个(如果我需要回调指针,std::function等)?

4 个答案:

答案 0 :(得分:4)

  

为什么这是什么理由?

通常,派生类只能访问同一派生类的受保护成员,而不能访问基类本身或具有相同基类的任意类。因此,B可以通过A访问B的受保护成员,但不能直接通过A访问。

  

有没有办法规避这个?

继承的成员也是B的成员,可以这样访问:

auto tmp = &B::foo;

答案 1 :(得分:2)

如果您能够指向A::foo,则可以使用它来对foo类型的对象或A类型的对象调用C。 {1}}:

A

相反,请指向class B : public A { public: void xx(A a) { auto tmp = &A::foo; a.*tmp(); } // illegal } ;这很好,因为你只能在类型为B::foo的对象上使用它。

答案 2 :(得分:1)

大概是为了安全。如果你能得到一个指向那个成员的指针,并且绝对没有任何警报响的话就把它交给任何人,这将是有风险的。

这是 a 解决方法(其他人可能会更清楚):

class A {
public:
    A() {auto tmp = &A::foo;}
protected:
    void foo() {}
};

class B : public A {
public:
    B() {auto tmp = &B::foo;}
};
编辑 - 认为你可能需要使用A :: foo,但你甚至不需要它。没有工作。参见:

Access to method pointer to protected method?

答案 3 :(得分:1)

您可以通过B访问它,即:

class B : public A {
public:
   B() {auto tmp = &B::foo;}
};

您无法从&A::Foo外部访问B,因为它受到保护,但您可以通过继承(因为Foo成为{{1}的成员通过继承),即通过调用B