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指针的理解和作用的更多相关文章

  1. 【C++】类中this指针的理解

    转自 苦涩的茶https://www.cnblogs.com/liushui-sky/p/5802981.html C++类中this指针的理解 先要理解class的意思.class应该理解为一种类型 ...

  2. 函数指针-如何理解typedef void (*pfun)(void)

    问题: 在刚接触typedef void (*pfun)(void) 这个结构的时候,存在疑惑,为什么typedef后只有一"块"东西,而不是两"块"东西呢?那 ...

  3. C++(extern关键字的理解和作用深入)

    extern关键字的理解和作用深入 extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数, 也会在当前文件的后面或者其它文件中定义 引 ...

  4. C语言教学--二维数组和指针的理解

    对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...

  5. 函数指针的理解 from 数据结构

    今天在学习数据结构中遇到一些问题,函数的指针不知道怎么用,给自己科普一哈 1 int LocateElem_Sq(SqList L, LElemType_Sq e, Status(*Compare)( ...

  6. C++中this指针的理解

    C++中this指针的理解 先要理解class的意思.class应该理解为一种类型,象int,char一样,是用户自定义的类型.用这个类型可以来声明一个变量,比如int x, myclass my等等 ...

  7. C++类中this指针的理解

    先要理解class的意思.class应该理解为一种类型,象int,char一样,是用户自定义的类型.用这个类型可以来声明一个变量,比如int x, myclass my等等.这样就像变量x具有int类 ...

  8. c++形参改变实参(对指针的理解

    这几天搞逻辑比较晕,居然把指针的概念都混淆了. eg:int *p;//当然不对指针初始化在有些编译器是通不过编译的,比如VS(尤其是选中了SDL) 指针p是一个对象,定义开始没有分配了内存空间,只是 ...

  9. C/C++学习笔记----指针的理解

    指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...

随机推荐

  1. NFS文件系统及搭建NFS共享服务

    一.什么是文件系统? 文件系统是对一个存储设备上的数据和元数据进行组织的一种机制.文件系统是在一个磁盘(包括光盘.软盘.闪盘及其它存储设备)或分区上组织文件方式方法,常见文件系统如ext2.ext3. ...

  2. java 与 iOS 平台概念比较

    java oc/swift jvm iphone jre runtime? jdk ios SDK spring xcode 生成的应用模版 服务器(tomcat) 系统的事件调度派发部分 class ...

  3. C#Winform窗体利用单例子窗体传值父窗体

    简述:最近在做C#和HALCON编程,要用到单例的参数由子窗体改变父窗体的值.此例为简化版 1,点击系统设置 2,弹出子窗体,在其输入修改参数后点修改按钮 3,点击确定按钮后,关闭子窗体后,主窗体te ...

  4. Reuse Implemented Functionality 重用实现功能

    A default XAF solution contains one platform-agnostic (shared) module and platform-dependent modules ...

  5. 简约清新日系你好五月通用PPT模板推荐

    模版来源:http://ppt.dede58.com/peixunyanjiang/26488.html

  6. SpringCloud(一):了解SpringCloud

    一.SpringCloud 简介 首先看看SpringCloud官方的介绍: Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由, ...

  7. Angular ElementRef详解

    一.为什么要用ElementRef Angular 的口号是 - "一套框架,多种平台.同时适用手机与桌面 (One framework.Mobile & desktop.)&quo ...

  8. 代码审计 => 74cms_v3.5.1.20141128 一系列漏洞

    0x01 前言 最近开始在学习代码审计了,以前几次学习代码审计都因为不知道如何下手,和代码的复杂就放弃了,这一次算是真正的认真学习,同时seay所编写的<代码审计 企业级Web代码安全架构> ...

  9. mysql定时任务(event事件)

    1.事件简介 事件(event)是MySQL在相应的时刻调用的过程式数据库对象.一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”. 事件和触发器类似,都是在 ...

  10. MD5是个好东西 / MD5 is a nice guy

    md5是一种摘要生成算法,通过对消息生成唯一摘要,可校验消息是否被篡改. 众所周知,md5广泛用在http接口通讯的安全控制上,通过在签名原始串后加上商户通信秘钥,进行MD5运算,形成的摘要字符串即为 ...