提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
说实话,前几篇文章写的确实不够详细,主要目的还是了为做笔记嘛,可能最近受了点刺激哈哈哈,觉得无论做什么还是需要认真对待的,所以我尽量写的详细一点。纯属小白,欢迎指正。
提示:以下是本篇文章正文内容,下面案例可供参考
一、this指针概念
在C++中,成员变量和成员函数是分开存储的。
每一个非静态成员函数值会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。那么问题是:这一块代码是如何区分哪个对象调用自己的呢?
所以,C++通过提供特殊的对象指针,this指针,解决上述问题,this指针指向被调用的成员函数所属的对象,通俗一点就是,谁调用它,它就指向谁。
- this指针是隐含在每一个非静态成员函数内的指针
- this指针不需要定义,直接使用即可。
二、this指针用途:
- 当形参和成员变量同名时,可用this指针来区分
- 在类的非静态成员函数中返回对象本身,可使用 return *this
代码示例1
代码如下(这个并不能达到我们的目的):
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age) //有参构造函数
{
age = age;
}
int age;
};
//1、解决名称冲突
void test01()
{
Person p1(18);
cout << "p1的年龄为:" << p1.age << endl;
}
int main()
{
test01();
return 0;
}
运行结果如下:
我们发现,最终p1.age的值并不是18,那这是为什么呢?
我们看一下这张图片:
当我把鼠标放到形参age的地方时,图片中有三个阴影,这说明编译器认为这三个age是一样的,但是注意了!我们person类里面声明的成员变量age并没有阴影,所以Person构造函数里面的age和成员变量age并不是一个age,所以我们就可以用this指针来告诉编译器,我想修改的其实是成员变量age。
正确代码如下(示例):
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age) //有参构造函数
{
this->age = age; //这里改了!!!!!!!
}
int age;
};
//1、解决名称冲突
void test01()
{
Person p1(18);
cout << "p1的年龄为:" << p1.age << endl;
}
int main()
{
test01();
return 0;
}
运行结果如下:
这样的结果才是我们想要的哦。
我们再来看一张图片:
加上this指针后,就能得到我们想要的结果,而且大家可以注意一下阴影部分,会发现,this->age就是p1对象里面的age,所以我们说,谁调用就指向谁。我们用p1调用了age, 那么this指针就指向p1.age所属的对象p1(this指向p1)。也就是说 this指针指向被调用的成员函数所属的对象。
但是我们通常都不这样写,而是这样写:
class Person
{
public:
Person(int age)
{
m_Age = age;
}
int m_Age;
};
我们也要注意养成一个好的编程习惯,其中m表示member。
代码示例2
我么先来看一下 下面这个代码
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age)
{
//this指针指向 被调用的成员对象 所属的对象
this->age = age;
}
void PersonAddAge(Person &p)
{
this->age += p.age;
}
int age;
};
void test02()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1);
cout << "p2的年龄为:" << p2.age << endl;
}
int main()
{
test02();
return 0;
}
运行结果如下:
从上面这个代码我们可以看出,p2的年龄加了10岁,但是p2只加了一次我觉得不够爽,我想让 p2.age 连续加很多次,那怎么办呢?这时就用到我们this指针的第二个用途了。
但在这之前,我们先看一下下面这个错误的代码:
既然想多加几次,我们就需要多次调用PersonAddAge()函数,如下:
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age)
{
//this指针指向 被调用的成员对象 所属的对象
this->age = age;
}
void PersonAddAge(Person &p)
{
this->age += p.age;
}
int age;
};
void test02()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
cout << "p2的年龄为:" << p2.age << endl;
}
int main()
{
test02();
return 0;
}
首先我们要知道这样写是错误的。p2是我们的一个对象,我们能够通过对象p2 调用PersonAddAge()函数,前面第一个调用是没有问题的,但是后面的就不行了,因为p2.PersonAddAge() 的返回类型是void,他不是对象,所以无法用 p2.PersonAddAge().PersonAddAge() 再次调用这个函数。但如果 p2.PersonAddAge() 返回的还是 p2, 那我们就可以继续调用PersonAddAge()函数了。所以,我们可以把返回类型由void改为Person &,并在函数体内加上 return *this。 这就是用了this的第二个用途 来返回 p2 这个对象本身,然后就可以连续调用该函数了。
正确代码如下(示例):
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age)
{
//this指针指向 被调用的成员对象 所属的对象
this->age = age;
}
//返回p2这个对象的本体,用引用的方式进行返回
Person& PersonAddAge(Person &p)
{
this->age += p.age;
//this指向p2, 而 *this 指向的就是p2这个对象的本体
return *this;
}
int age;
};
//返回对象本身用 return *
void test02()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); //链式编程思想
cout << "p2的年龄为:" << p2.age << endl;
}
int main()
{
test02();
return 0;
}
运行结果如下:
运行后就能得到我们先要的结果啦!!看到这里辛苦啦,不知道我说清楚了没有,但我尽力了。阳光正好,但bug不少。