转自:http://bbs.csdn.net/topics/350227597
经常可以看到,比如按钮的回调,网络返回的回调函数
(m_pSelectorTarget->*m_pSucceedCallFuncO)(NULL);
m_pSucceedCallFuncO是私有函数的指针。可是却能够运行,
很久以前就发现了这个问题。
为啥不报访问私有函数的错误那?
你这个就好比:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class PrivateMemberFuncPtr
{
public:
void bind();
private:
void print()
{
printf("success\n");
}
};
void (PrivateMemberFuncPtr::*ptr)();
void PrivateMemberFuncPtr::bind()
{
ptr=&PrivateMemberFuncPtr::print;
}
int main()
{
PrivateMemberFuncPtr obj;
obj.bind();
((&obj)->*ptr)();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
struct Test {
private :
int i;
public:
void bind();
void print()
{
cout<<i<<endl;
}
};
int Test::* ptr;
void Test::bind(){
ptr=&Test::i;
}
int main()
{
Test obj;
obj.bind();
obj.print();
obj.*ptr=10;
obj.print();
system("pause");
return 0;
}
|
实际上你通过bind()这个函数将内部实现暴露给别人,使得别人可以绕过权限来直接使用私有的东西。
打个不恰当的比方,你一个公司外面的人偷不到公司的内部资料,但是他通过公司内部的一个员工拿到一些公司的内部资料,然后就他可以利用这些资料为所欲为了。
private区段的访问控制是编译期的事件,通过模板类的虚函数实现中用成员函数指针调用是运行期方法。
实际上,无论私有还是公有的成员函数,编译后就是一个普通函数(扩展为需要this指针作为第一个参数),因此函数地址也就确定了,在运行期可以通过call或jmp指令跳转到该函数执行(只要有合法的this指针所指的对象)。