背景:

  c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译。c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数。翻译时,将class翻译成struct、对象翻译成结构变量是显而易见的,但是对类的成员函数应该如何翻译?对“my.modify();”这样通过一个对象调用成员函数的语句,又该如何翻译呢?

c语言只有全局函数,因此成员函数只能被翻译成全局函数;“my.modify();”这样的语句也只能翻译成普通的调用全局函数的语句。那如何让翻译后的modify全局函数还能作用在my这个结构变量上呢?答案是引入“this指针”。

示例:

下面来看一段c++程序到c程序的翻译。

c++程序:

class CCar{
public:
int price;
void SetPrice(int p);
}; void CCar::SetPrice(int p){
price=p;
} int main(){
CCar car;
car.SetPrice(20000);
}

翻译后的c程序:

struct CCar{
int price;
}; void SetPrice(CCar* this,int p){
this->price=p;
} int main(){
struct CCar car;
SetPrice(&car,20000);
}  

可以看出,类被翻译成结构体,对象被编译成结构变量,成员函数被翻译成全局函数。但是c程序的全局函数SetPrice比c++的成员函数SetPrice多了一个参数,就是“CCar*this”。“car.SetPrice(20000);”被翻译成“SetPrice(&car,20000);”,后者在执行时,this形参指向的正是car这个变量,因而达到了SetPrice函数作用在car变量上的效果。

this指针的作用:

  实际上,现在的c++编译器从本质上来说也是按上面的方法来处理成员函数和对成员函数的调用的,即非静态成员函数实际上的形参个数比程序员写的多一个。多出来的参数就是所谓的“this指针”。这个”this指针“指向了成员函数作用的对象,在成员函数执行的过程中,正是通过“this指针”才能找到对象所在的地址,因而也就能找到对象的所有非静态成员变量的地址。

示例:

#incldue<iostream>
using namespace std;
class A{
int i;
public:
void Hello(){cout<<"hello"<<endl;}
}; int main(){
A*p=NULL:
p->Hello();
}

  程序的输出结果是:

hello

在上面的程序中,p明明是一个空指针,但它还是能正确调用A的成员函数Hello,因为,参考上面c++到c程序的白泥臆,“p->Hello()”实质上应该是“Hello(p)”,在翻译后的Hello函数中,cout语句没有用到this指针,因此依然可以输出结果。如果Hello函数中有对成员变量的访问,则程序就会出错。

this指针的使用:

c++规定,在非静态成员函数内部可以直接使用this关键字,this就代表指向该函数所作用的对象的指针。

示例:

#include<iostream>
using namespace std;
class A{ public:
double real,imga;
A(double r,double i):real(r),imga(i){}
A addone(){
this->real++;
return *this;
}
}; int main(){
A c1(1,1),c2(0,0);
c2=c1.addone();
cout<<c2.real<<","<<c2.imga<<endl;
}

输出为 2,1

第9行,this指针的类型是A*。因为this指针就指向函数所作用的对象,所以this->real和real是完全等价的。“*this”代表函数所作用的对象,因此执行第16行,进入addone函数后,“*this”实际上就是c1。因此c2的值会变得和c1相同。

注意:

因为静态成员函数并不作用于某个对象,所以在其内部不能使用this指针。

新标准c++程序设计

转发请注明出处

this指针------新标准c++程序设计的更多相关文章

  1. 指针和动态分配内存 (不定长度数组)------新标准c++程序设计

    背景: 数组的长度是定义好的,在整个程序中固定不变.c++不允许定义元素个数不确定的数组.例如: int n; int a[n]; //这种定义是不允许的 但是在实际编程中,往往会出现要处理的数据数量 ...

  2. 正确处理类的复合关系------新标准c++程序设计

    假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...

  3. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  4. 多态实现的原理------新标准c++程序设计

    “多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...

  5. 类的互相包含------新标准c++程序设计

    #include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...

  6. 多态的作用-游戏编程展示------新标准c++程序设计

    游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...

  7. 类与类之间的两种关系------新标准c++程序设计

    在c++中,类和类之间有两种基本关系:复合关系和继承关系. 复合关系也称为“has a”关系或“有”的关系,表现为封闭类,即一个类以另一个类的对象作为成员变量. 继承关系也称为“is a”关系或“是” ...

  8. 复制构造函数被调用的三种情况------新标准c++程序设计

    1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意 ...

  9. 析构函数的调用------新标准c++程序设计

    示例1: #include<iostream> using namespace std; class CDemo{ public: ~CDemo(){cout<<"d ...

随机推荐

  1. 转:oracle几组重要的常见视图-v$undostat,v$open_cursor,v$rowcache,v$session_longops,v$waitstat

    v$undostat 本视图监控当前实例中undo空间以及事务如何运行.并统计undo空间开销,事务开销以及实例可用的查询长度. V$UNDOSTAT中的常用列 Endtime:以10分钟为间隔的结束 ...

  2. vue-cli中的ESlint配置文件eslintrc.js详解

    本文讲解vue-cli脚手架根目录文件.eslintrc.js eslint简介 eslint是用来管理和检测js代码风格的工具,可以和编辑器搭配使用,如vscode的eslint插件 当有不符合配置 ...

  3. VS2017自动添加头部注释

    让VS自动生成类的头部注释,只需修改两个文集即可,一下两个路径下个有一个 Class.cs文件 D:\Program Files (x86)\Microsoft Visual Studio\2017\ ...

  4. PHP开发环境正确的错误信息处理

    正确记录配置 php.ini display_errors = On error_reporting = E_ALL log_errors = On error_log = F:/data/php/e ...

  5. [原创]Mybatis特殊值Enum类型转换器-ValuedEnumTypeHandler

    引言 typeHandlers 阅读官方文档 typeHandlers 一节{:target="_blank"} MyBatis 在预处理语句(PreparedStatement) ...

  6. python之operator模块

    python3中已经没有cmp函数,被operator模块代替,在交互模式下使用时,需要导入模块. 在没有导入模块情况下,会出现 提示找不到cmp函数了,那么在python3中该如何使用这个函数呢? ...

  7. AMF解析之数据类型定义 (转)

    目录(?)[-] OpenRTMFPCumulus Primer15AMF解析之数据类型定义 数据类型 undefined Type null Type false type true type in ...

  8. Jsp页面中的中文乱码问题解决

    Jsp页面中的中文乱码问题解决 在编写Jsp页面的时候,发现写入其中的中文在浏览器浏览的时候会出现乱码的情况. 出现乱码的原因分析: 因为页面中对自己的编码格式的声明和页面的实际编码格式不相同,而浏览 ...

  9. MySQL与SQLServer的update left join语法区别

    需求: 表A 字段 A_ID, A_NAME, B_ID 表B 字段 B_ID, B_NAME 需求把A的所有A_NAME更新为相应的B的 B_NAME. mysql做法: UPDATE A LEFT ...

  10. go语言 robfig/cron包 实现定时 调用

    package main import ( "github.com/robfig/cron" "time" "fmt" "os&q ...