关于成员函数CTestClass::Function的补充说明
这个函数是一个普通的成员函数 , 它在编译器的处理下,会成为类似如下的代码:
void Function( const CTestClass * this ) // ①
{
printf("This is a test function.\n");
}
那么p-Function();一句将被编译器解释为:
Function( p );
这就是说,普通的成员函数必须经由一个对象来调用(经由this指针激活②) 。那么由上例的delete之后,p指针将会指向一个无效的地址,然而p本身是一个有效的变量 , 因此编译能够通过 。并且在编译通过之后,由于CTestClass::Function的函数体内并未对这个传入的this指针进行任何的操作,所以在这里,“野指针”便成了一个看似安全的东西 。
然而若这样改写CTestClass::Function:
void CTestClass::Function( void )
{
m_nInteger = 0;
}
那么它将会被编译器解释为:
void Function( const CTestClass * this )
{
this-m_nInteger = 0;
}
你看到了 , 在p-Function();的时候,系统将会尝试在传入的这个无效地址中寻找m_nInteger成员并将其赋值为0,剩下的我不用说了——非法操作出现了 。
至于virtual虚函数,如果在类定义之中将CTestClass声明为虚函数:
class CTestClass
{
public:
// ...
virtual void Function( void );
};
那么C++在构建CTestClass类的对象模型时,将会为之分配一个虚函数表vptr(可以从sizeof看出来) 。vptr是一个指针 , 它指向一个函数指针的数组 , 数组中的成员即是在CTestClass中声明的所有虚函数 。在调用虚函数的时候,必须经由这个vptr,这也就是为什么虚函数较之普通成员函数要消耗一些成本的缘故 。以本例而言 , p-Function();一句将被编译器解释为:
(*p-vptr[1])( p ); // 调用vptr表中索引号为1的函数(即Function)③
上面的代码已经说明了,如果p指向一个无效的地址,那么必然会有非法操作 。
备注:
①关于函数的命名 , 我采用了原名而没有变化 。事实上编译器为了避免函数重载造成的重名情况,会对函数的名字进行处理,使之成为独一无二的名称 。
②将成员函数声明为static,可以使成员函数不经由this指针便可调用 。
③vptr表中 , 索引号0为类的type_info 。
关于go语言中有野指针吗和go语言%v的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。
推荐阅读
- 真实赛车是谁开发的游戏,真实赛车有什么车
- 怎么用我的手机连接你,我的手机怎么能连接你
- 养成游戏物语,一个养成游戏叫什么物语
- c语言如何跳出一个函数 c语言中如何跳出函数
- pg库一般加什么索引,pg数据库建立索引
- 使命召唤射击游戏剪辑视频,使命召唤枪战视频
- 新手做抖音直播教学多久,自学抖音直播
- go语言实现注册功能 go语言创建项目
- redis微信模板推送,redis redistemplate