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指针,


最新文章

  1. ABP文档 - 目录
  2. Thread与Runnable的一个小陷阱
  3. expdp / impdp 用法详解
  4. PAT 基础编程题 4-11 求自定类型元素序列的中位数(希尔排序)
  5. UVa 1584 Circular Sequence --- 水题
  6. 切换PS工具栏里的快捷键
  7. [置顶] Objective-C ,ios,iphone开发基础:在UITextField输入完以后,隐藏键盘,
  8. Android硬件抽象层(HAL)概要介绍和学习计划
  9. thinkPHP四种URL访问方式(二)
  10. Struts2 stracture
  11. JavaScript一个拖动元素的实例
  12. 微信小程序开发
  13. 【ASP.NET MVC 学习笔记】- 14 HtmlHlper的扩展方法
  14. notepad++上直接运行python文件
  15. svn各种表示含义及解决
  16. oracle 查看后台正在执行的脚本
  17. asp.net NPOI导出xlsx格式文件,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
  18. SkylineGlobe 如何实现绘制圆形Polygon和对图层的圆形范围选择查询
  19. How can R and Hadoop be used together?
  20. 如何在Vblock里配置Boot from SAN

热门文章

  1. jQuery 源码解析(二十七) 样式操作模块 坐标详解
  2. ETCD:在容器中运行etcd集群
  3. HBuildX报错此插件的使用依赖于外部应用程序eslint,本机未检测到此应用
  4. Netty实战:设计一个IM框架
  5. 【NOI 2011】阿狸的打字机
  6. 【TencentOS tiny】深度源码分析(5)——信号量
  7. 清新简约风格毕业论文答辩PPT模板推荐
  8. Java工程师学习指南
  9. 甲方安全之安卓App第三方加固对比
  10. CentOS7 安装frp与开机启动