大家好,我是苏貝,本篇博客带大家了解C++的this指针,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
目录
- 1 this指针的引出
- 2 this指针的特性
1 this指针的引出
我们先来定义一个日期类Date
问:Date的对象d1,d2调用的Print是同一个函数吗?是的,根据我们之前学的,类的对象里只存储成员变量,成员函数在公共代码区中。我们也来证明一下,来看汇编代码,确实是的
现在我们给2个对象初始化
问:既然2个对象的Print是同一个函数,且函数体中没有关于不同对象的区分,那么为什么d1调用的Print函数知道3个变量是d1初始化的值而非d2初始化的值?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数this,让this指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过this去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。也就是说,this指针对用户来说是隐含的
即编译器看到的Print函数
编译器看到的2个对象调用Print函数
编译器看到的给我们看也并不默认啊,我们在数据结构里写的实现顺序表里也会这样写。
所以引入隐含的this指针后,d1调用的Print函数就知道3个变量是d1初始化的值而非d2初始化的值
2 this指针的特性
-
this指针的类型:类的类型* const,即成员函数中,不能改变this指针的指向(指向调用该成员函数的对象)。
-
只能在“成员函数”的内部使用
-
this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。所以对象中不存储this指针。
-
this指针是“成员函数”隐含的第一个指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递
-
虽然成员函数有隐含的实参(调用该函数的对象的地址)和形参(this指针),但是我们不能写出来
-
不能将形参this写出来,但是我们可以在成员函数内使用
-
不能修改this指针的指向
直接插入排序的特性总结:
问题:this存在哪里?
a. 栈区 b. 堆区 c. 静态区 d. 常量区 e. 对象中
答案:a ,因为它是函数形参,所以在栈区。
先排除e.对象中,它是成员函数的形参,成员函数在公共代码区而非对象中,形参肯定也不能在对象中。堆区是有关动态开辟内存的,排除。静态区存全局变量和静态变量(被static修饰的变量),排除。
会不会因为this的类型是 类的类型* const,有const所以觉得是常量区呀?不是的,C++中const修饰的变量不是在常量区。看下图
变量i和p都是有const修饰,j是普通变量,但它们的地址是连着的,都是在栈区。这里面只有p指向的“hello world“是在常量区。
问题:this指针可以为空吗?
1. 下面程序编译运行结果是?
A、编译报错 B、运行崩溃 C、正常运行
答案:C.正常运行
语法没有问题,所以不是编译报错。可p是空指针,p->解引用了,不是应该运行崩溃吗?不是的,编译器只会按需求做事,不是写了解引用它就会解引用,而是需要用到指针指向的内容时才会解引用。回到本题,Print函数不在对象里,所以根本不需要堆指针p解引用,因此程序正常运行。
2. 下面程序编译运行结果是?
A、编译报错 B、运行崩溃 C、正常运行
答案:B. 运行崩溃
语法没有问题,所以不是编译报错。这个PrintA函数需要用到对象里的成员变量,所以编译器要对p解引用,p是空指针,因此运行崩溃
好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️