浅析C++中的this指针

有下面的一个简单的类:

class CNullPointCall{public:    static void Test1();    void Test2();    void Test3(int iTest);    void Test4();private:    static int m_iStatic;    int m_iTest;};

int CNullPointCall::m_iStatic = 0;

void CNullPointCall::Test1(){    cout << m_iStatic << endl;}

void CNullPointCall::Test2(){    cout << "Very Cool!" << endl;}

void CNullPointCall::Test3(int iTest){    cout << iTest << endl;}

void CNullPointCall::Test4(){    cout << m_iTest << endl;}

那么下面的代码都正确吗?都会输出什么?

CNullPointCall *pNull = NULL; // 没错,就是给指针赋值为空pNull->Test1(); // call 1pNull->Test2(); // call 2pNull->Test3(13); // call 3pNull->Test4(); // call 4

你肯定会很奇怪我为什么这么问。一个值为NULL的指针怎么可以用来调用类的成员函数呢?!可是实事却很让人吃惊:除了call 4那行代码以外,其余3个类成员函数的调用都是成功的,都能正确的输出结果,而且包含这3行代码的程序能非常好的运行。

经过细心的比较就可以发现,call 4那行代码跟其他3行代码的本质区别:类CNullPointCall的成员函数中用到了this指针。

对于类成员函数而言,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。 当程序被编译之后,此成员函数地址即已确定。而成员函数之所以能把属于此类的各个对象的数据区别开, 就是靠这个this指针。函数体内所有对类数据成员的访问, 都会被转化为this->数据成员的方式。

而一个对象的this指针并不是对象本身的一部分,不会影响sizeof(“对象”)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类 的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上 this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

对于上面的例子来说,this的值也就是pNull的值。也就是说this的值为NULL。而Test1()是静态函数,编译器不会给它传递this指 针,所以call 1那行代码可以正确调用(这里相当于CNullPointCall::Test1());对于Test2()和Test3()两个成员函数,虽然编译器会 给这两个函数传递this指针,但是它们并没有通过this指针来访问类的成员变量,因此call 2和call 3两行代码可以正确调用;而对于成员函数Test4()要访问类的成员变量,因此要使用this指针,这个时候发现this指针的值为NULL,就会造成 程序的崩溃。

其实,我们可以想象编译器把Test4()转换成如下的形式:

void CNullPointCall::Test4(CNullPointCall *this){    cout << this->m_iTest << endl;}

而把call 4那行代码转换成了下面的形式:

CNullPointCall::Test4(pNull);

所以会在通过this指针访问m_iTest的时候造成程序的崩溃。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
, 指针
, int
, private
, static
void
c this指针、c this指针使用、c语言 this指针、c中的this指针、c中this指针,以便于您获取更多的相关知识。

时间: 2024-09-15 06:22:02

浅析C++中的this指针的相关文章

深入浅析JavaScript中的Function类型_javascript技巧

Function是javascript里最常用的一个概念,javascript里的function是最容易入手的一个功能,但它也是javascript最难理解最难掌握的一个概念. 1. Function类型是js中引用类型之一,每个函数实际上都是Function类型的实例对象,具有自己的属性和方法.正因为函数式对象,所以函数名实际上也是一个指向函数对象的指针. 2. 常用的函数定义方式 1. 函数声明: function sum(a , b ){ return a+b; } 2. 表达式: va

通过CSS让网页中的鼠标指针一直都是手形

如何让网页中的鼠标指针一直都是手形呢?很简单,在网页body上方加入如下的CSS代码就OK了,试试吧. <style type="text/css"><!--body{cursor:pointer;}--></style> 以下是HTML网页特效代码,点击运行按钮可查看效果: [Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

构造函数中的this指针

-------------------------------原理------------------------------- 某些人认为不应该在构造函数中使用this指针,因为这时this对象还没有完全形成. 但是,只要小心,是可以在构造函数中使用this指针的: ●在函数体中 ●初始化列表中 因为"对象还没有完全形成"不意味着"什么都没有". 在进入构造函数(及其chaining)之前,Compiler会: ●给class的instance分配内存 ●建立运行

内存陷阱:驯服C++中的野指针

什么是野指针? 一个母亲有两个小孩(两个指针),一个在厨房,一个在卧室,(属于不同的代码块,其生存期不同)母亲让在厨房的小孩带一块蛋糕(指针指向的对象)给在卧室的小孩,这样在卧室的孩子才肯写作业.但这个在厨房的小孩比较淘气,他在走出厨房时自己将蛋糕吃了,没能带出来.而在卧室的没有吃到蛋糕,所以不肯完成他的作业.结果母亲却不知道卧室的孩子没有吃到蛋糕,还以为作业完了.结果第二天她就被老师召唤到办公室了.事情麻烦了. 这样,那个在卧室的孩子就是野指针了,因为他没有得到应得的蛋糕,不能完成母亲交给他的

浅析AngularJS中的生命周期和延迟处理

  这篇文章主要介绍了浅析AngularJS中的生命周期和延迟处理,是AngularJS中较为核心的深层次内容,需要的朋友可以参考下 这里,我们再讨论一些常用的高级的控制反转容器(Inversion of Control containers):延迟加载(lazy-loading),生命周期管理(lifetime management),以及延迟的创建/处理(deferred creation/resolution). 延迟加载(Lazy-Loading) 所谓延迟加载就是当你需要用到对象时候才

C++中的函数指针与函数对象的总结

以下是对C++中的函数指针与函数对象的使用进行了详细的分析介绍,需要的朋友可以参考下   篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址. 函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. 函数指针的声明方法:数据类型标志符 (指针变量名) (形参列表): 一般函数的声明为: int func ( int x );而一个函数指针的声明方法为:int (*func) (int x);前面的那个(

浅析javascript中函数声明和函数表达式的区别

这篇文章主要介绍了浅析javascript中函数声明和函数表达式的区别,需要的朋友可以参考下     javascript中声明函数的方法有两种:函数声明式和函数表达式. 区别如下: 1).以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的. 2).以函数声明的方法定义的函数,函数可以在函数声明之前调用,而函数表达式的函数只能在声明之后调用. 3).以函数声明的方法定义的函数并不是真正的声明,它们仅仅可以出现在全局中,或者嵌套在其他的函数中,但是它们不能出现在循环,条件或者

qlabel-Qt如何获取窗口中的部件指针

问题描述 Qt如何获取窗口中的部件指针 我在窗口中定义了64个QLabel作为8乘8的矩阵,每个Label的名字都不同,现在我想 在一个按钮的槽函数里面获取某个特定的Label,比如对比数据知道第二行第三列的 Label需要改变Text,那么经过运算这是"Label-11"那么我想获取这个Label的 指针,我发现使用this->findChild("Label-11")不行,获取不到,我应该怎么获 取到呢? 解决方案 QList<QLabel *>

C++函数参数中引用和指针有什么区别?

问题描述 C++函数参数中引用和指针有什么区别? C++函数参数中引用和指针有什么区别? 解决方案 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址: 引用是某块内存的别名. ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指针需要解引用: 3. 引用只能在定义时被初始化一次,之后不可变:指针可变: 引用"从一而终" ^_^ 4. 引用没有 const,指针有 const,const 的指针不可变: 5. 引用不能