matlab this指针,C++ this指针(直戳本质)

为了能让大家看清 this 指针的本质,我们会先讲一点 C++ 的历史——C++ 程序到C程序的翻译过程。

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

C++ 是在C语言的基础上发展而来的,第一个 C++ 的编译器实际上是将 C++ 程序翻译成C语言程序,然后再用C语言编译器进行编译。

C语言没有类的概念,只有结构,函数都是全局函数,没有成员函数。翻译时,将 class 翻译成 struct、对象翻译成结构变量是显而易见的,但是对类的成员函数应该如何翻译?对myCar.Modify();这样通过一个对象调用成员函数的语句,又该如何翻译呢?

C语言中只有全局函数,因此成员函数只能被翻译成全局函数;myCar.Modify();这样的语句也只能被翻译成普通的调用全局函数的语句。那如何让翻译后的 Modify 全局函数还能作用在 myCar 这个结构变量上呢?答案就是引入“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);

return 0;

}

翻译后的C程序(此程序应保存为扩展名为 .c 的文件后再编译):

struct CCar

{

int price;

};

void SetPrice(struct CCar* this, int p)

{

this->price = p;

}

int main()

{

struct CCar car;

SetPrice(&car, 20000);

return 0;

}

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

思考题:以上翻译还不完整,因为构造函数的作用没有体现出来。思考构造函数应该如何翻译。另外,静态成员函数和静态成员变量应如何翻译?

this 指针的作用

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

下面程序的运行结果能够证明这一点:

#include

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 函数中有对成员变量的访问,则程序就会出错。

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

#include

using namespace std;

class Complex {

public:

double real, imag;

Complex(double r, double i) : real(r), imag(i) {}

Complex AddOne()

{

this->real++;

return *this;

}

};

int main()

{

Complex cl(1, 1), c2(0, 0);

c2 = cl.AddOne();

cout << c2.real << "," << c2.imag << endl; //输出 2,1

return 0;

}

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

因为静态成员函数并不作用于某个对象,所以在其内部不能使用 this 指针;否则,这个 this 指针该指向哪个对象呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF自定义控件 —— 装饰器

摘自&#xff1a;http://www.cnblogs.com/Curry/archive/2009/09/16/1567757.html 顾名思义就是装饰用的&#xff0c;也就是说不改变原有的控件结构&#xff0c;但可以为控件添加一些新的功能&#xff0c;或是为控件的显示外观增加些东西。如MSDN中的例子&#xff1a; 本来Text…

matlab填充点面,求大神指点绘制空间内散点图的包络面,,,散点程序如下

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼E[];a0;b0;c0;for Zp-50:2:50for Xp-200:2:200for Yp-200:2:200P1_1[cos(b)*cos(c) -cos(b)*sin(c) sin(b) Xp;sin(a)*sin(b)*cos(c)cos(a)*sin(c) cos(a)*cos(c)-sin(a)*sin(b)*sin(c) -sin(a)*cos(b) Yp;sin(a)*sin(c)-cos(a)*si…

对微软Microsoft Dynamics CRM 的认识

MS CRM的认识 技术层面&#xff1a; MS CRM使用了当前最为流行的Web Service作为数据交互的手段&#xff0c;这给我们的二次开发和系统级的集成带来了无可比拟的方便性、易用性。我们不用关心如何去访问CRM数据库&#xff0c;只需要关心我们要访问CRM中的哪一个对象&#xff0c…

yii+php+当前目录,Yii常用路径方法总结

Yii框架中的一些常见的路径方法的使用方法总结。在控制器添加CSS文件或JavaScript文件&#xff1a;Yii::app()->clientScript->registerCssFile(Yii::app()->baseUrl./css/my.css);Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl./css/m…

Java递归函数

原文&#xff1a;http://blog.163.com/zhuliqing_001/blog/static/293340982010101046597/ 1 、递归函数的定义&#xff1a; 答&#xff1a;递归函数即自调用函数&#xff0c;在函数体内直接或间接的调用自己&#xff0c;即函数的嵌套是函数本身。 2 、递归方式&#xff1a;递归…

php的ddd,在MVC框架中实现DDD – PHP

在mvc中,模型是一个层,它包含所有的域业务逻辑.在域驱动设计中,业务逻辑可以分为各种构建块.在域驱动设计域模型中.A domain model is a system of abstractions that describes selectedaspects of a sphere of knowledge,influence or activity (a domain).The model can the…

Netty Associated -- ByteBuf

ByteBuf ByteBuf是Netty的Server与Client之间通信的数据传输载体.他提供了一个byte数组(byte[])的抽象视图 buffer创建 我们推荐通过一个Unpooled的帮助方法来创建新的buffer而不是通过调用独立的构造器来创建 随机访问索引 就像普通的原声字节数组一样, ByteBuf使用零基坐标(z…

php 根号2计算过程,根号2以及π的计算--关于无理数的畅想

[导读]这两篇文章里&#xff0c;我发现不需要那些老师教的范式也能很好地理解那些现代概念&#xff0c;并且理解的更深刻。这两篇文章里&#xff0c;我发现不需要那些老师教的范式也能很好地理解那些现代概念&#xff0c;并且理解的更深刻。我一般假设自己从来没有学过微积分&a…

oracle对象权限 函数,oracle的系统和对象权限

alter any cluster 修改任意簇的权限alter any index 修改任意索引的权限alter any role 修改任意角色的权限alter any sequence 修改任意序列的权限alter any snapshot 修改任意快照的权限alter any table 修改任意表的权限alter any trigger 修改任意触发器的权限alter clust…

批处理程序实例

一、交互界面设计 没啥说的&#xff0c;看看高手设计的菜单界面吧&#xff1a;echo offclstitle 终极多功能修复:menuclscolor 0Aecho.echo echo 请选择要进行的操作&#xff0c;然后按回车echo echo.echo 1.网络修复及上网相关设置,修复IE,自定义屏蔽网站echo.echo 2.病毒专杀…

oracle 10g dsg,【ORACLE】relink oracle 10g 数据库

通常要迁移一个数据库&#xff0c;我们会使用1 冷备份&#xff0c;整个数据库迁移&#xff0c;2 rman duplicate 功能进行复制到本机或者复制到异机&#xff0c;前面两种都必须先在目标库上安装软件。这里测试另外一种方法&#xff1a;对于单实例数据库&#xff0c;复制整个ora…

任务分配与时间估计

各成员的任务分配与时间估计如下&#xff1a; 项目所需总时间为&#xff1a; 转载于:https://www.cnblogs.com/buaa-smile/p/3383374.html

vbs 连oracle 负载均衡,(原)QTP中用VBS调用PLSQL并执行相关语句

今天工作的需求是要在录制一段web程序之前要调用plsql并执行一段数据库代码清空相关数据才能做web录制测试&#xff0c;本来是想用QTP直接录制plsql的&#xff0c;但是后来发现自己对qtp录制window application并不是很了解&#xff0c;选定了 Automation菜单下的Record and Ru…

unity中发布android时候出现这样的提示错误:error:device not found

原因很简单&#xff0c;就是你没开启安卓设备&#xff0c;无论是安卓手机还是安卓虚拟器。。 解决办法&#xff1a;只要开启安卓虚拟器或者连接手机即可 再次打开cmd命令窗口&#xff0c;找到apk文件所在路径&#xff0c;例如&#xff1a; D: 回车&#xff08;我的是在d盘根目录…

Oracle 每个session的限制,限制oracle普通用户能且只能kill自己的会话

声明&#xff1a;仅用于测试环境方便调试&#xff0c;不可能应用于生产环境&#xff1b;故请勿加入到程序源代码来实现自动杀进程。只需一个参数&#xff0c;就能kill用户自己的会话&#xff0c;请小心操作&#xff0c;以免误kill进程。使用方法&#xff1a;新开一个session后&…

Hessian简介

Hessian Hessian是一个轻量级的remoting onhttp工具&#xff0c;使用简单的方法提供了RMI的功能。 相比WebService&#xff0c;Hessian更简单、快捷。采用的是二进制RPC协议&#xff0c;因为采用的是二进制协议&#xff0c;所以它很适合于发送二进制数据目 录 1介绍 1.1 注意事…

linux 以某个用户执行,Linux root用户肿么以制定的用户去执行某个程序。

chmod o-x m1说明&#xff1a;命令格式&#xff1a;chmod [options] mode files只能文件属主或特权用户才能使用该功能来改变文件存取模式。mode可以是数字形式或以who opcode permission形式表示。who是可选的&#xff0c;默认是a(所有用户)。只能选择一个opcode(操作码)。可指…

linux启动sh文件命令,Linux下如何写 .sh 脚本启动 项目

Linux下如何写 .sh 脚本启动 项目创建文件 mealcoupon.sh内容如下&#xff1a;#!/bin/bash#这里可替换为你自己的执行程序&#xff0c;其他代码无需更改APP_NAMExhqy_yzf-1.0.0.war#项目的路径(替换成你项目的路径)PROJECT_LOCATION/home/xpro/xhqy_jt#使用说明&#xff0c;用…