this指针

一.对象的存储

每个对象中的数据成员都分别占有存储空间,如果对同
一个类定义了n个对象,则有n组同样大小的空间以存放
n个对象中的数据成员。但是,不同对象都调用同一个
函数代码段。

#include <iostream>
using namespace std;
class Box
{ private:
int height; int width; int length;
public:
Box(int h=0, int w=0, int len=0)
{ height=h; width=w; length=len; }
int volume( )
{return height*width*length;} 
};
int main( )
{ Box a,b,c; cout<<sizeof(Box)<<endl;
return 0; 
}
运行结果   12

空间内只是存放着数据成员,函数在公共函数代码块中

1.问题:
当不同对象的成员函数引用数据成员时,如何保证引用的是所
指定的对象的数据成员呢?
假如,
对于上例程序中定义的Box类,定义了3个同类对象a,b,c。
如果有a.volume( ) ,应该是引用对象a中的height,width和length,计算出长方体a的体积。
如果有b.volume( ) ,应该是引用对象b中的height,width和length,计算出长方体b的体积。
而现今都用同一个函数段,系统怎样使它分别引用a或b中的数据成员呢?
2.解决:在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的,称为this指针。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。
例如,当调用成员函数a.volume()时,编译系统就把对象a的起始地址赋给this指针,于是在成员函数引用数据成员时,就按照this的指向找到对象a的数据成员。volume函数要计算heightwidthlength的值,实际上是执行:
(this->height)(this->width)(this->length)
由于当前this指向a,因此相当于执行:
(a.height)(a.width)( a.length)
这就计算出长方体a的体积。

二.this指针

1.this指针是隐式使用的,它作为参数被传递给成员函数。
成员函数volume的定义如下:
int Box::volume( )
{ return (heightwidthlength); } //隐含使用this指针
C++把它处理为:
int Box::volume(Box this)
{ return (this->height * this->width * this->length); }
即在成员函数的形参表列中增加一个this指针。
在调用该成员函数时,实际上是用以下方式调用的:
a.volume(&a);
将对象a的地址传给形参this指针,然后按this的指向去引用其他成员。
2.编程序者不必人为地在形参中增加this指针,也不必将对象a的地址传给this指针,编译系统可以自动实现。
例如在Box类的volume函数中,下面两种表示方法都是合法的、相互等
价的。
return (height * width * length); //隐含使用this指针
return (this->height * this->width * this->length); //显式使用this指针

可以用
this表示被调用的成员函数所在的对象,this就是this所指向
的对象,即当前的对象。
例如在成员函数a.volume( )的函数体中,如果出现
this,它就是本对象a 。上面的return语句也可写成
**return((*this).height * (this).width * (this).length);

三.需要显式引用this指针的三种情况

(1)在类的非静态成员函数中返回类对象本身或对象的引用的时候,直接使用 return *this,返回本对象的地址时,return this。

#include <iostream>
#include <cstring>
using namespace std;
class Person{
public:
Person(string n, int a){
name = n; //这里的 name 等价于this->name
age = a; //这里的 age 等价于this->age
}
int get_age() const{ return age; }
Person& add_age(int i){age += i; return *this; }
private:
string name;
int age;
};
int main()
{
Person Li("Li", 20);
cout<<"Li age = "<< Li.get_age()<<endl;
cout<<"Li add age = "<< 
Li.add_age(1).get_age()<<endl; 
//增加1岁的同时,可以对新的年龄直接输出;
return 0;
}
程序执行结果为:
Li age = 20
Li add age = 21

(2)当参数与成员变量名相同时,如this->x = x,不能写成x = x。

#include <iostream>
using namespace std;
class Point
{
public:
int x;
Point ():x(0){}
Point (int a){ x=a; }
void print(){ cout<<"x = "<<x<<endl; }
void set_x(int x){ x = x; }
};
int main( ) {
Point pt(5);
pt.set_x(10);
pt.print();
return 0;
}

此处的x是函数形参中的x,因为参数是局部变量,在函数体中优先访问(同名覆盖),因此此处无法访问到类成员中的x。
程序执行结果为:
x = 5
若将set_x函数改为:
void set_x(int x) { this->x = x; }
程序执行结果为:
x = 10

(3)避免对同一对象进行赋值操作,判断两个对象是否相同时,使用this指针

#include <iostream>
using namespace std;
class Location
{
int X,Y; //默认为私有的
public:
void init(int x,int y) { X =x; Y = y;};
void assign(Location& pointer);
int GetX(){ return X; }
int GetY(){ return Y; }
};
void Location::assign(Location& pointer)
{
if( &pointer!=this ) 
//同一对象之间的赋值没有意义,所以要保证pointer不等于this
{ X=pointer.X; Y=pointer.Y; }
}
int main(){
Location x;
x.init(5,4);
Location y;
y.assign(x);
cout<<"x.X = "<< x.GetX()<<" x.Y = "<<x.GetY();
cout<<"y.X = "<< y.GetX()<<" y.Y = "<<y.GetY();
return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值