一、什么是this指针

要想理解什么是this指针,首先必须理解在C++中是如何为类的对象分配内存空间的。

 #include<iostream>
using namespace std;
class Student{
public:
void CountTotal();
void GetName(char name[]);
void GetAmount();
void GetPrice();
void GetTotal();
private:
char Name[24]; //占24个字节
int Amount; //占4个字节
float Price; //占4个字节
float Total; //占4个字节
}; int main(){
Student stu;
cout<<"对象stu占的字节数:"<<sizeof(stu)<<endl;
}

由上例可以看出,当用类Student定义一个对象stu时,内存开辟36个字节的空间用来存储这个对象,而内存开辟的空间刚好分配给了这个对象的四个成员变量(Name、Amount、Price、Total),那么问题来了,成员函数所占的内存空间为什么在对象定义时没有分配给所定义的对象呢?

其实原因很简单,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个函数体。当程序被编译之后,此成员函数的地址就已经确定了。如果为每个类的对象都开辟空间来存储这个对象的成员函数,由于每个对象的成员函数的函数体代码都相同,只是所要传递的实参不一样,这样做会造成内存的浪费。那么类的成员函数又是如何识别不同对象传递过来的实参呢?没错,就是靠this指针。

二、this指针的本质

我们先来看一个struct的例子

 #include<iostream>
#include<string>
using namespace std;
struct Student{
string Name;
int Age;
string Gender;
};
void Init(Student *_this,string name,int age,string gender){ //对对象进行初始化 _this->Name=name;
_this->Age=age;
_this->Gender=gender;
}
int main(){
Student stu1,stu2,stu3;
Init(&stu1,"Tomwenxing",23,"male");
Init(&stu2,"Jack",22,"male");
Init(&stu3,"Ellen",18,"female");
return 0;
}

如上例,_this指针的作用是指向需要进行操作的对象,其作用和C++类中的this指针相似,只不过类中的this指针是隐式的插入在类中的成员函数中,不需要编程者手动的定义,以类Student中的成员函数GetAmount为例:

  //相当于void GetAmount(Student* this)
void Student::GetAmount(){
//相当于return this->return;
return Amount;
} int main(){
Student stu;
//相当股GetAmount(&stu);
stu.GetAmount();
return 0;
}

那这就是this指针的本质的全部么?既然this指针的作用是指向需要进行操作的对象,并且是隐式的自动插入在类中的成员函数中,那我们在定义类的成员函数时是否可以手动的更改this指针的指向呢?

  void Student::GetAmount(){
this=NULL; //错误:c++不允许更改this指针的指向
return Amount;
}

由上可知是不允许的,因为this指针是一个指针常量,即this指针一旦初始化,它就再也不能改变自己的指向,将会始终指向自己需要操作的对象,仍以Student类中的GetAmount为例:

  //相当于void GetAmount(Student* const this)
void Student::GetAmount(){
//相当于return this->return;
return Amount;
}

因此this指针的本质是一个隐式插入类成员函数体中,用来指向需要操作的对象的指针常量。

C++:this指针的简单理解的更多相关文章

  1. git的简单理解及基础操作命令

    前端小白一枚,最近开始使用git,于是花了2天看了廖雪峰的git教程(偏实践,对于学习git的基础操作很有帮助哦),也在看<git版本控制管理>这本书(偏理论,内容完善,很不错),针对所学 ...

  2. 谈谈自己对C语言中函数指针的一些理解 (第一次写博客,有点小兴奋哈)

    1.函数指针声明的格式及简单的使用 (1)格式:(返回值)(*函数指针名)(参数列表)    例如:声明一个无参数无返回值的函数指针(void)(*p)(void). (2)将函数指针指向某个无参数无 ...

  3. 简单理解ECMAScript2015中的箭头函数新特性

    箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...

  4. C++:引用的简单理解

    前言:引用是C++一个很重要的特性,最近看了很多有关引用的资料和博客,故在此对引用的相关知识进行总结 一.什么是引用 引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作 ...

  5. 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制

    [原创]分布式之数据库和缓存双写一致性方案解析(三)   正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...

  6. 转 PV操作简单理解

    传送门 PV操作简单理解 进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下: 进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作 ...

  7. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  8. 简单理解JavaScript原型链

    简单理解原型链 什么是原型 ? 我是这样理解的:每一个JavaScript对象在创建的时候就会与之关联另外一个特殊的对象,这个对象就是我们常说的原型对象,每一个对象都会从原型"继承" ...

  9. TCP-三次握手和四次挥手简单理解

    TCP-三次握手和四次挥手简单理解 背景:TCP,即传输控制协议,是一种面向连接的可靠的,基于字节流的传输层协议.作用是在不可靠的互联网络上提供一个可靠的端到端的字节流服务,为了准确无误的将数据送达目 ...

随机推荐

  1. mysql 生成UUID() 即 ORACLE 中的guid()函数

    MYSQL 生成UUID 即 guid 函数-- 带 - 的UUIDselect UUID() -- 去掉 - 的UUIDselect replace(uuid(),'-','') 一个表的数据插入另 ...

  2. 解决vscode换行光标跳转行首

    这个问题是由于设置自动保存而造成的. 解决方法1:取消自动保存. 解决方法2:在首选项的设置里加上"files.autoSaveDelay": 10000,延迟一小会自动保存的时间 ...

  3. Quick find Helper

    using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; /// <summary> /// 视图 ...

  4. MySQL用全库备份数据恢复单表数据

    备份数据库时,采用了全库备份,但是因为某些原因需要回滚一个表的数据到备份数据库上,如果回滚整个库就比较费时间,因为可能这个表只有几十M,但是其它表可能有十几上百G,这时候就需要将需要恢复的表提取出来了 ...

  5. python教程(三)·函数进阶(上)

    在介绍了函数定义的方法后,再来介绍一些进阶知识 参数收集 有时候我们需要参数的数量是任意的,比如print函数的参数的数量是任意的,print函数的内部实现我们不探究,但是单单是参数数量可变这一方面实 ...

  6. 【8086汇编-Day1】预备知识

    菜鸟的8086汇编入门之旅,偶有错处恭请大佬们指正. Ⅰ· 闲说一下 我为什么学汇编?相对于晦涩难懂的01010101011010机器语言(高低电平变化驱动机器做出不同反应),汇编语言用更便于记忆和使 ...

  7. java入门---运算符&算术运算符&自增自减运算符&关系运算符&位运算符

        计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 ...

  8. react work with angularjs together

    http://blog.500tech.com/using-reactjs-with-angularjs/ http://www.funnyant.com/reactjs-what-is-it/ ht ...

  9. 实验楼学习linux第一章第四节linux目录结构及文件基本操作

    linux目录结构及文件基本操作 常用命令 切换目录 cd 当前目录 . 上一级目录 .. (.和..开头的都是隐藏文件) 查看隐藏文件 ls -a 上一级所在目录 - 当前用户home目录 ~ 获取 ...

  10. 20155226 mini DC 课堂测试补交

    由于电脑突然出了点问题,我没有完成mini DC这个测试,现将测试内容及结果补交 题目如下 提交测试截图和码云练习项目链接,实现Linux下dc的功能,计算后缀表达式的值 代码如下 MyDC.clas ...