C++ this指针的理解和作用
01 C++ 程序到 C 程序的翻译
要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码
class Car
{
public:
int m_price; // 成员变量
void SetPrice(int p) // 成员函数
{
m_price = p;
}
};
int main()
{
Car car;
car.SetPrice(20000); // 给car对象m_price成员变量赋值
return 0;
}
C 语言是没有类定义的class
关键词,但是有跟class
类似的定义,那就是结构体struct
。
m_price
变量是Car
类的成员变量,那么我们可以把Car
类和成员变量翻译成如下的 C 代码:
// 结构体Car
struct Car
{
// price变量是属于Car结构体这个域里的变量
int price;
};
SetPrice
函数是Car
类的成员函数,但是 C 程序里是没有成员函数这种概念的,所以只能把成员函数翻译成全局的函数:
// 参数1:结构体Car的指针
// 参数2:要设置的价格变量
void SetPrice(struct Car* this, int p)
{
this->price = p; // 将传入的Car结构体的price变量赋值
}
为什么要加个 this 的指针呢?我们继续往下看。
在这里我们把上面main
函数下面的 C++ 程序翻译 C 程序是这样的:
int main()
{
struct Car car;
SetPrice( &car, 20000);
return 0;
}
所以最终把上述的 C++程序 转换成C 程序的代码如下:
struct Car
{
int price;
};
void SetPrice(struct Car* this, int p)
{
this->price = p;
}
int main()
{
struct Car car;
SetPrice( &car, 20000); // 给car结构体的price变量赋值
return 0;
}
02 this指针的作用
其作用就是指向成员函数所作用的对象,
所以非静态成员函数中可以直接使用 this 来代表指向该函数作用的对象的指针。
#include <iostream>
class Car
{
public:
int m_price;
void PrintPrice()
{
std::cout << m_price << std::endl;
}
void SetPrice(int p)
{
this->m_price = p; // 等价于 m_price = p;
this->PrintPrice();// 等价于 PrintPrice();
}
Car GetCar()
{
return *this; // 返回该函数作用的对象
}
};
int main(void)
{
Car car1, car2;
car1.SetPrice(20000);
// GetCar()成员函数返回所作用的car1对象,所把返回的car1赋值给了car2
car2 = car1.GetCar();
car2.PrintPrice();
return 0;
}
输出结果:
20000
20000
接下来我们下面的代码,你觉得输出结果是什么呢?会出错吗?
class A
{
int i;
public:
void Hello() { cout << "hello" << endl; }
};
int main()
{
A * p = NULL;
p->Hello(); //结果会怎样?
}
答案是正常输出hello,你可能会好奇明明 p 指针是空的,不应该是会程序奔溃吗?别着急,我们先把上面的代码转换C程序,就能理解为什么能正常运行了。
void Hello() { cout << "hello" << endl; }
# 成员函数相当于如下形式:
void Hello(A * this ) { cout << "hello" << endl; }
p->Hello();
# 执行Hello()形式相当于:
Hello(p);
所以,实际上每个成员函数的第一个参数默认都有个指向对象的 this 指针,上述情况下如果该指向的对象是空,相当于成员函数的第一个参数是NULL
,那么只要成员函数没有使用到成员变量,也是可以正常执行。
下面这份代码执行时,就会奔溃了,因为this指针是空的,使用了 空的指针指向了成员变量i
,程序就会奔溃。
class A
{
int i;
public:
void Hello() { cout << i << "hello" << endl; }
// ->> void Hello(A * this ) { cout << this->i << "hello" << endl; }
};
int main()
{
A * p = NULL;
p->Hello(); // ->> Hello(p);
}
03 this指针和静态成员函数
静态成员函数是不能使用 this 指针,因为静态成员函数相当于是共享的变量,不属于某个对象的变量。
04 小结
通过将C++程序翻译成C程序的方式,来理解 this 指针,其作用就是指向非静态成员函数所作用的对象,每个成员函数的第一个参数实际上都是有个默认 this 指针参数。
静态成员函数是无法使用this指针,
C++ this指针的理解和作用的更多相关文章
- 【C++】类中this指针的理解
转自 苦涩的茶https://www.cnblogs.com/liushui-sky/p/5802981.html C++类中this指针的理解 先要理解class的意思.class应该理解为一种类型 ...
- 函数指针-如何理解typedef void (*pfun)(void)
问题: 在刚接触typedef void (*pfun)(void) 这个结构的时候,存在疑惑,为什么typedef后只有一"块"东西,而不是两"块"东西呢?那 ...
- C++(extern关键字的理解和作用深入)
extern关键字的理解和作用深入 extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数, 也会在当前文件的后面或者其它文件中定义 引 ...
- C语言教学--二维数组和指针的理解
对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...
- 函数指针的理解 from 数据结构
今天在学习数据结构中遇到一些问题,函数的指针不知道怎么用,给自己科普一哈 1 int LocateElem_Sq(SqList L, LElemType_Sq e, Status(*Compare)( ...
- C++中this指针的理解
C++中this指针的理解 先要理解class的意思.class应该理解为一种类型,象int,char一样,是用户自定义的类型.用这个类型可以来声明一个变量,比如int x, myclass my等等 ...
- C++类中this指针的理解
先要理解class的意思.class应该理解为一种类型,象int,char一样,是用户自定义的类型.用这个类型可以来声明一个变量,比如int x, myclass my等等.这样就像变量x具有int类 ...
- c++形参改变实参(对指针的理解
这几天搞逻辑比较晕,居然把指针的概念都混淆了. eg:int *p;//当然不对指针初始化在有些编译器是通不过编译的,比如VS(尤其是选中了SDL) 指针p是一个对象,定义开始没有分配了内存空间,只是 ...
- C/C++学习笔记----指针的理解
指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...
随机推荐
- vue 客户端渲染和服务端渲染
参考链接 https://www.cnblogs.com/tiedaweishao/p/6644267.html
- ABP之Logging
服务器端 ABP使用Castle Windsor的日志设施.它可以使用不同的日志库:Log4Net.NLog.Serilog等等.Castle为所有日志程序库提供了一个公共接口,这样,我们可以独立的使 ...
- python爬虫爬小说网站涉及到(js加密,CSS加密)
我是对于xxxx小说网进行爬取只讲思路不展示代码请见谅 一.涉及到的反爬 js加密 css加密 请求头中的User-Agent以及 cookie 二.思路 1.对于js加密 对于有js加密信息,我们一 ...
- docker: manifest for elasticsearch:latest not found
今天在docker安装es出现坑,是这样. 使用: docker pull elasticsearch 提示:manifest for elasticsearch:latest not found如图 ...
- 清新三角格子风工作报告季度总结年终汇报通用PPT模板
选好合适的PPT模板,确定好主题,一个漂亮的PPT首先要简洁,其次文字不要太多,能用图片或视频讲解的最好用图片或视频.做好ppt后,对于讲解演示,也要提前做好练习准备. 模版来源:http://ppt ...
- spark SQL、RDD、Dataframe总结
- $和jquery的关系
$和jquery的关系 $其实是jQuery的别名 一般直接使用$符号 在许多JavaScript库中都会有$作为标记.如果同时使用多个JavaScript库时难免会出现冲突. 解决方法:重新设置jQ ...
- Django注意知识点(二)
Tinymce富文本 前台和后台的使用 一,后台 Admin 1. 于 settings.py 文件中修改 INSTALLED_APPS 2. 于 settings.py 文件中增添如下配置 # 富文 ...
- TensorFlow从1到2(十二)生成对抗网络GAN和图片自动生成
生成对抗网络的概念 上一篇中介绍的VAE自动编码器具备了一定程度的创造特征,能够"无中生有"的由一组随机数向量生成手写字符的图片. 这个"创造能力"我们在模型中 ...
- Vue入门(二)
1.vue3.0安装 cnpm install -g @vue/cli 或者 yarn global add @vue/cli //创建项目 vue create hello-world //运行 n ...