C++中this指针的理解与作用详解

 更新时间:2019-12-02 07:04:02   作者:佚名   我要评论(0)

01 C++ 程序到 C 程序的翻译


要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码


class Car
{
public:
int m_price; // 成员变量
void

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指针用法详解及实例
  • 详解C++中的this指针与常对象
  • C/C++静态类和this指针详解及实例代码
  • C++基础之this指针与另一种“多态”
  • C++编程指向成员的指针以及this指针的基本使用指南
  • C++ 中的this指针详解及实例
  • 深度理解c++中的this指针

相关文章

  • C++中this指针的理解与作用详解

    C++中this指针的理解与作用详解

    01 C++ 程序到 C 程序的翻译 要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码 class Car { public: int m_price; // 成员变量 void
    2019-12-02
  • Node.js控制台彩色输出的方法与原理实例详解

    Node.js控制台彩色输出的方法与原理实例详解

    前言 我们都知道,在nodejs环境下使用普通的console.log,console.error,console.info输出都是不会有颜色的,如果你不知道,那你现在知道啦&#128527;。在这种情况下,
    2019-12-02
  • Node.js中console.log()输出彩色字体的方法示例

    Node.js中console.log()输出彩色字体的方法示例

    1. 代码样例 console.log('\033[42;30m DONE \033[40;32m Compiled successfully in 19987ms\033[0m') 2. 输出结果 3. 解释 不难发现样例中的关键的
    2019-12-02
  • 详解C语言数组中是以列优先吗

    详解C语言数组中是以列优先吗

    如果我们按照C语言的方式存储它,也就是行优先存储的话,那么在内存中,它的形状是这样的: 这种存储方式又被称作C contiguous array。 C语言数组结构列优先顺序存
    2019-12-02
  • 如何利用node.js开发一个生成逐帧动画的小工具

    如何利用node.js开发一个生成逐帧动画的小工具

    前言 在实际工作中我们已经下下来不下于一万个npm包了,像我们熟悉的 vue-cli,react-native-cli 等,只需要输入简单的命令 vue init webpack project,即可快速帮我
    2019-12-02
  • angular异步验证防抖踩坑实录

    angular异步验证防抖踩坑实录

    前言 本周的一个需求是在一个异步验证上加上防抖,防抖,以前也接触过,依稀记得不难,就没再去看angluar的官方文档,直接就开始google写了,然后……一不小心就掉坑
    2019-12-02
  • Python函数的默认参数设计示例详解

    Python函数的默认参数设计示例详解

    在Python教程里,针对默认参数,给了一个“重要警告”的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3)) 默认值只会执行
    2019-12-02
  • 如何利用Golang解析读取Mysql备份文件

    如何利用Golang解析读取Mysql备份文件

    前言 前期误操作,导致数据库表删除,虽然数据量不多,但是通过binlog恢复比较麻烦,通过备份文件来恢复,备份文件达36个G打开都是问题; 使用备份文件恢复 大
    2019-12-02
  • 关于Yii2框架跑脚本时内存泄漏问题的分析与解决

    关于Yii2框架跑脚本时内存泄漏问题的分析与解决

    现象 在跑 edu_ocr_img 表的归档时,每跑几万个数据,都会报一次内存耗尽 PHP Fatal error: Allowed memory size of 134217728 bytesexhausted (tried toalloc
    2019-12-02
  • 利用python实现冒泡排序算法实例代码

    利用python实现冒泡排序算法实例代码

    冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的
    2019-12-02

最新评论