C++ this指针的概念和使用

this指针的概念:

在C++中成员变量和成员函数是分开存储的。

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

那么问题是:这一块代码是如何区分哪个对象调用自己的呢?

c++通过提供特殊的对象指针,this指针,解决上述问题。

关键:this指针 指向 被调用的成员函数所属的 对象! 谁调用了成员函数,this就指向谁

this指针是隐含在每一个 非静态成员函数 内的一种指针(内置的,我一直都在你身体里哦~)。

this指针不需要定义,直接使用即可。

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分;
  • 在类的非静态成员函数中返回对象本身,可使用return *this。

问题描述

this指针主要用于解决两个问题:
1、解决名称冲突
2、返回对象本身用*this
现在我们创建一个类:

class Person
{
public:

	Person(int age)
	{
		//1、当形参和成员变量同名时,可用this指针来区分
        // age = age; // 这样cout输出的是30190,都是age,相当于有参构造函数没有给成员变量赋值
		this->age = age; //点击右值的age会发现它和形参有阴影,点击左值的age会发现它和成员变量以及调用处的age有阴影
        //this指针指向 被调用的成员函数 所属的 对象
	}
    void PersonAddAge(Person &p){
        this->age += p.age;
    }

	Person& PersonAddPerson(Person p)
	{
		this->age += p.age;
		//this指向p2的指针,而*this指向的就是 p2本身
		return *this; //得用Person&
	}

    Person PersonAddPerson2(Person p)
	{
		this->age += p.age;
		//this指向p2的指针,而*this指向的就是 p2本身
		return *this; //不加&
	}

	int age;
};

这个类里面有构造函数Person、非静态成员函数PersonAddAgePersonAddPersonPersonAddPerson2以及非静态成员变量int age

详细解释:

1、解决名称冲突:

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;
}

main函数调用test01时,如果采用age=age的方式在构造函数中赋值,会出现输出一个随机数的错误,比如输出30190,而非10。主要原因还是在于形参和成员变量同名,相当于没有赋值操作。把构造函数里的东西都注释了会发现也是输出一个随机的数字。因此需要用this指针的方式解决名称冲突。

2、返回对象本身用*this:

第一种情况:不加return返回值

void test02()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
    p2.PersonAddAge(p1); //成员函数PersonAddAge属于p2,所以里面的this指针指向p2,计算结果就是p2的age加上p1的age
	cout << "p2.age = " << p2.age << endl;

    //error: invalid use of ‘void’,所以p2.PersonAddAge(p1)必须返回p2这个对象它才能继续 .
    // p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
    // cout << "p2.age = " << p2.age << endl;
}

可以对p2本身修改,输出:
p1.age = 10
p2.age = 20
但是如果p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);这样累加就会报错:

error: invalid use of ‘void

所以p2.PersonAddAge(p1)必须返回p2这个对象它才能继续 .

第二种情况:加return返回值,返回Person & (引用返回)

void test02()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
    p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
    cout << "p2.age = " << p2.age << endl;
    
}

调用PersonAddPerson进行累加,输出:
p1.age = 10
p2.age = 40 (加了三次10,都是对p2这个对象进行操作的)
那么为什么Person要加&呢?
因为引用指向本身的内存,不加引用相当于拷贝了(拷贝构造函数),而拷贝指向另一个内存。
请看下面的例子:

第三种情况:加return返回值,返回Person (值返回)

void test02()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
    Person p3 = p2.PersonAddPerson2(p1).PersonAddPerson2(p1).PersonAddPerson2(p1);
    cout << "p2.age = " << p2.age << endl;
    cout << "p3.age = " << p3.age << endl;
}

调用PersonAddPerson2进行累加,输出:
p1.age = 10
p2.age = 20
p3.age = 40
分析:执行p2.PersonAddPerson2(p1)会返回一个新的对象 p‘ ,它的age值是20,p2的age值由于this指针所以也是20,然后继续执行.PersonAddPerson2(p1),就会又创建一个新的对象 p’’ ,它的age值是30,而p2的age值依然是20,因为后面的操作和p2没关系了,依次类推把最后的结果赋值给p3,p3age值为40。

因此要注意区分 引用返回 和 值返回 的区别

值得注意的是,请不要把 值传递方式返回值方式返回局部对象 混淆了。
值方式返回局部对象这个链接里有关于它的描述,使用linux系统时会有一个RVO机制,它会少一次拷贝构造和析构的开销(编译器帮助我们作了优化)。

补充知识:指针常量和常量指针的区别

  • 37
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值