C++ 派生类中受保护的成员函数地址不可访问

C++ 派生类中受保护的成员函数地址不可访问,c++,inheritance,protected,member-function-pointers,C++,Inheritance,Protected,Member Function Pointers,将foo改为公共工程。同样,打印&B::foo也有效。你能解释一下为什么我们不能得到基类的受保护成员函数的地址吗?看来我找到了答案。如果我们可以得到成员函数的指针,我们可以为类型为A(而不是this)的其他对象调用它,这是不允许的 不允许在派生类中为非this的对象调用受保护的成员函数。拿着指针会让人觉得很暴力 我们可以这样做: main.cpp: In member function ‘void B::bar()’: main.cpp:5: error: ‘void A::foo()’ is

将foo改为公共工程。同样,打印
&B::foo
也有效。你能解释一下为什么我们不能得到基类的受保护成员函数的地址吗?

看来我找到了答案。如果我们可以得到成员函数的指针,我们可以为类型为
A
(而不是
this
)的其他对象调用它,这是不允许的

不允许在派生类中为非
this
的对象调用受保护的成员函数。拿着指针会让人觉得很暴力

我们可以这样做:

main.cpp: In member function ‘void B::bar()’:
main.cpp:5: error: ‘void A::foo()’ is protected
main.cpp:13: error: within this context
make: *** [all] Error 1
#包括
甲级{
受保护的:
void foo()
{}
};
B类:公共A{
公众:
空条()
{
void(A::*fptr)(=&A::foo;
obj;
(obj.*fptr)();
//obj.foo();//这也未编译。
}
};
int main()
{
B B;
b、 bar();
}

我很好奇,尝试了以下示例:

#包括
使用名称空间std;
甲级{
公众:
void foo()
{
}
};
B类:公共A{
公众:
空条()
{
printf(“%p\n”,(&A::foo));
printf(“%p\n”,(&B::foo));
}
};
int main()
{
B B;
b、 bar();
}

实际上,我看到
&A::foo
=
&B::foo
,所以对于基类的受保护成员,您可以使用派生类成员获取地址。我假设在虚拟函数的情况下,这将不起作用

B
允许访问
A
的受保护成员,只要通过类型为
B
的对象执行访问。在您的示例中,您试图通过
A
访问
foo
,在该上下文中,
B
是否派生自
A
是无关的

根据N3337,§11.4/1[等级保护]

如前所述,当非静态数据成员或非静态成员函数是其命名类(11.2)的受保护成员时,将应用第11条前面所述之外的附加访问检查 早些时候,授予对受保护成员的访问权,因为引用发生在某个类的朋友或成员中
C
。如果访问要形成指向成员的指针(5.3.1),嵌套名称说明符应表示
C
或a 从
C
派生的类。所有其他访问都涉及(可能是隐式的)对象表达式(5.2.5)。在这种情况下,对象表达式的类应为
C
或派生自
C
的类。[示例:

-[结束示例]


您的示例与
D2::mem
中的代码非常相似,这表明试图通过
B
而不是
D2
形成指向受保护成员的指针是格式错误的。

好问题。看起来像是未来的修正!谁能解释一下语法
intb::*pmi_B
?是
pmi_B
pmi_B2
int值还是指针?你为什么在星号前面叫
B::
?@Sterling这是一个
main.cpp: In member function ‘void B::bar()’:
main.cpp:5: error: ‘void A::foo()’ is protected
main.cpp:13: error: within this context
make: *** [all] Error 1
#include <iostream>

class A {
protected:
    void foo()
    {}
};

class B : public A {
public:
    void bar()
    {
        void (A::*fptr)() = &A::foo;

        A obj;
        (obj.*fptr)();

        // obj.foo(); //this is not compiled too.    
    }
};

int main()
{
    B b;
    b.bar();
}
 class B {
 protected:
   int i;
   static int j;
 };
 class D1 : public B {
 };
 class D2 : public B {
   friend void fr(B*,D1*,D2*);
   void mem(B*,D1*);
 };
 // ...
 void D2::mem(B* pb, D1* p1) {
   // ...
   int B::* pmi_B = &B::i; // ill-formed
   int B::* pmi_B2 = &D2::i; // OK
   // ...
 }
 // ...