C++:this指针的简单理解
一、什么是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指针的简单理解的更多相关文章
- git的简单理解及基础操作命令
前端小白一枚,最近开始使用git,于是花了2天看了廖雪峰的git教程(偏实践,对于学习git的基础操作很有帮助哦),也在看<git版本控制管理>这本书(偏理论,内容完善,很不错),针对所学 ...
- 谈谈自己对C语言中函数指针的一些理解 (第一次写博客,有点小兴奋哈)
1.函数指针声明的格式及简单的使用 (1)格式:(返回值)(*函数指针名)(参数列表) 例如:声明一个无参数无返回值的函数指针(void)(*p)(void). (2)将函数指针指向某个无参数无 ...
- 简单理解ECMAScript2015中的箭头函数新特性
箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...
- C++:引用的简单理解
前言:引用是C++一个很重要的特性,最近看了很多有关引用的资料和博客,故在此对引用的相关知识进行总结 一.什么是引用 引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作 ...
- 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制
[原创]分布式之数据库和缓存双写一致性方案解析(三) 正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...
- 转 PV操作简单理解
传送门 PV操作简单理解 进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下: 进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作 ...
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
input屏蔽历史记录 设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处 ;(function($){$.ex ...
- 简单理解JavaScript原型链
简单理解原型链 什么是原型 ? 我是这样理解的:每一个JavaScript对象在创建的时候就会与之关联另外一个特殊的对象,这个对象就是我们常说的原型对象,每一个对象都会从原型"继承" ...
- TCP-三次握手和四次挥手简单理解
TCP-三次握手和四次挥手简单理解 背景:TCP,即传输控制协议,是一种面向连接的可靠的,基于字节流的传输层协议.作用是在不可靠的互联网络上提供一个可靠的端到端的字节流服务,为了准确无误的将数据送达目 ...
随机推荐
- TopJUI Combobox onSelect 事件失效BUG
版本:2.2.8 onChange : function(b, c) 两个参数:当前选择后在Combobox中显示的数据,实际是textField:另一个是改变前的数据 onSelect : func ...
- 什么是设计模式?【php】
原文地址:https://www.cnblogs.com/zhuiluoyu/p/5818974.html 什么是设计模式? 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经 ...
- ionic 环境搭建
1.安装nodejs (8.4.0) 下载地址 https://nodejs.org/zh-cn/ 2.Java jdk 版本号 jdk1.8.0_121 3.安装 cordova npm ins ...
- MongoDB的高级使用
MongoDB的高级使用 1. Mongdb的索引备份以及和python交互 t255为mongodb中的集合 1.1 创建索引 索引的特点:提高查找的效率 不创建索引的情况下的查询: for(i=0 ...
- linux 命令 uniq
linux命令uniq去重 实例详细说明linux下去除重复行命令uniq 一,uniq干什么用的 文本中的重复行,基本上不是我们所要的,所以就要去除掉.linux下有其他命令可以去除重复行,但是我觉 ...
- PHP-掌握基本的分布式架构思想
虽然说写PHP目前都是接触的业务代码,发现写久了,也要熟悉相应的架构 在高并发,高可用的系统下,都是使用高性能的分布式架构,最近在学习相关知识 分享一张图片: 欢迎关注公众号[phper的进阶之路], ...
- PHP递归无限分类,数组和直接输出。
去年在一家公司做项目开发,用到商城三级分类,看了之前的程序员写的分类也是头大,三级分类,循环套循环三次( foreach(){ foreach(){ foreach(){ } } } ),然后写了一个 ...
- Go语言 异常panic和恢复recover用法
Go语言 异常panic和恢复recover用法 背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在 ...
- The Road to learn React书籍学习笔记(第二章)
The Road to learn React书籍学习笔记(第二章) 组件的内部状态 组件的内部状态也称为局部状态,允许保存.修改和删除在组件内部的属性,使用ES6类组件可以在构造函数中初始化组件的状 ...
- 20155212 mybash的实现
mybash的实现 题目 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 准备 通过man命令了解fork ...