为什么不能存储基类的函数指针?

时间:2010-02-22 12:49:57

标签: c++ function-pointers

以下代码为void b() { m = &A::a; };提供了编译错误,指出A::a()受到保护。 (它是 - 但这应该没问题)
但是编译器在编写B::a()时并不在意。尽管两者的意思相同,但我更倾向于A::a(),因为它明确指出a()是在A中定义的。

所以 A::a()被禁止的原因是什么?? 的修改
如果在A::a()中允许B::b(),可能会有人找到一个有问题的示例。如果有这样的例子,我会将其标记为问题的答案 的 /修改

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdio>

class A {
protected:
  void a(){ std::cout << "A::a()" << std::endl; };
};

typedef void (A::*f)();
class B : public A {
public:
  void b() { m = &A::a; }; // wont compile
  // void b() { m = &B::a; }; // works fine
  void c() { (this->*m)(); };
protected:
  f m;
};

int main(){
  B b;
  b.b();
  b.c();
}

// compile with
// g++ -Wall main.cpp -o main

代码说明:
在B中,我想存储一个指向A中方法的函数指针,以便稍后在B::c()中调用它。是的,这也发生在现实生活中。 :-)

3 个答案:

答案 0 :(得分:2)

因为否则外界可以找到这个受保护的成员:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11174

另见http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00610.html

答案 1 :(得分:1)

原因应该类似于你不能在B中做到这一点的原因:

class B: public A
{
    //...
    void foo(A& x) {
        x.a(); //error
    }

    void foo(B& x) {
        x.a(); //OK
    }
};

受保护并不意味着B可以访问任何类的A部分,只要它是A /从A派生。受保护的东西仅适用于此B和B的其他实例

答案 2 :(得分:0)

您尝试通过全局命名空间访问受保护的成员(A :: a is :: A :: a here),请改用B :: A :: a。