一段很简单的,困惑的程序
#include <iostream>
using namespace std;
class A
{
public:
void Func(void){ cout << "Func of class A" << endl; }
};
A* Test(void)
{
A *p;
A a;
p = &a; // 注意 a 的生命期
return p;
}
void main()
{
// 这段程序搞笑了
A *q;
/*q = Test();*/
q = NULL;
q->Func();
system("pause");
}
代码如上,输出结果为“Func of class A”,可是我明明将q变为空指针了。
如果去掉代码“q = NULL;”,编译出错。
如果取消注释/*q = Test();*/,不论是否注释“q = NULL;”,结果还是输出“Func of class A”,可是栈里面的a对象明明已经被自动销毁了,这个时候返回的q应该是野指针才对吧?
这一切的一切,是为啥呢?难道C++和C的底层原理不同?
请各路大神指教,谢谢。
[解决办法]
这个问题属于C++的对象模型问题,其实这个问题并不是那么简单的。如果感兴趣的话可以看看Lippman的杰作《
深度探索C++对象模型》(Inside The C++ Object Model)里面解释的很清楚了。
简单的说C++的对象模型中只有成员数据,而没有成员函数,成员函数是用一个函数表来维护的,里面有一个用来查找的函数指针。你可以在VS下或gcc中打印一下这个类的结构,就可以证实了。简单的说,函数的地址其实已经固定了,只要你这个指针类型仍然是这个类,就可以直接访问这个函数,而不需要管是否实例化(指针会自己调用类内部的函数表寻找成员函数地址)
[解决办法]