C++ 派生类中受保护的成员函数地址不可访问
将foo改为公共工程。同样,打印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
&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
// ...
}
// ...