关于空指针类型的类变量的成员函数访问的问题

下面代码会有什么输出?

#include <iostream>
using namespace std;

class A
{
public:
	void fun()
	{
		cout<<"fun"<<endl;
	}
	virtual void vfun()
	{
		cout<<"vfun"<<endl;
	}
private:
	int a;
};

int main()
{
	A *a = NULL;
	a->fun();
	a->vfun();
	system("pause");
	return 0;
}


fun输出fun,

vfunc爆异常错误

---------------------------------------------

为什么有这样的结果?

  1.  从c++ 对象模型中知道,类的非虚成员函数和普通c的成员函数没有什么区别,而数据成员是每个类的实例化对象独享,虚函数会放在一个vptr指针指向的表,那个表存有函数的入口地址.

            比如 上述的func() 可能会有这个形式:

                          void func(A* this)

                           {}

    2.   在编译的时候,func这个函数直接会被汇编到text段里面,加载到内存后,其地址及入场等等信息都是完整存在的.

           我们在main你们调用这个函数的这句代码会直接引用到text段里面函数对于的地址,这个值可以说是死的。所以对象即便为空也是没关系的.

    3.虚函数的地址虽然也和一般函数一样在内存中加载了,但是虚函数不是在编译时刻求值的,而是动态时刻。这个动态时刻的概念就是,作为入参或者类的继承类型的实例化地址对应的具体函数的地址.通过visual studio或gcc反汇编代码,会发现往往都是在类对象实例化的时候,在构造函数里面插入的。这个地方 a这个指针显然没有new从而没有调用构造函数,所以看其vptr指针(vs貌似叫做vftable)可以肯定地址是空的.所以会爆错!

  4.如果a作为栈变量或者堆类型new出肯定都是不会爆错!

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值