首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

一段很简单的,迷惑的程序

2013-12-02 
一段很简单的,困惑的程序#include iostreamusing namespace stdclass A{public:void Func(void){ cout

一段很简单的,困惑的程序
#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中打印一下这个类的结构,就可以证实了。简单的说,函数的地址其实已经固定了,只要你这个指针类型仍然是这个类,就可以直接访问这个函数,而不需要管是否实例化(指针会自己调用类内部的函数表寻找成员函数地址)
[解决办法]

引用:
那为何,必须至少先为对象指针q赋值为NULL呢?
既然函数地址已经是固定的了,为何我q是野指针的时候,就不能调用Func()函数了?


楼主有没有在出现错误之后继续执行程序呢,若继续执行也会出现Func()的调用结果,和将q赋值为null的输出结果是一样的,也就是说出现错误,只是编译器要检查p又没定义,至于p指向的A对象存不存在并不重要,至于原因,上面讲了很多。

热点排行