看到一个C++视频教程里关于this指针讲解的时候多次用到了引用,老师的代码如下:
class Person {
public:
Person(int age)
{
this -> age = age;
}
Person& PersonAddAge(Person &p)
{
this->age += p.age; //把别人的age加到自己上面
//this指向p2的指针,而*this指向的是p2这个对象的本体
return *this;
}
int age;
};
void test01()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
cout<<"p2的年龄为:"<<p2.age<<endl;
}
int main() {
test01();
system("pause");
return 0;
}
其运行结果为:p2的年龄为:40
我关注的是其中的下面这行代码里为什么需要这两个引用符号,因为*this已经可以表示指向原对象了,那为啥要多次一举呢?
首先第二个引用符号在这里是不需要的(老师的附属文件里也没有第二个引用符号,可能讲的时候没注意),放在这里不算错只是引用的作用是让被引用变量的值一起改变,而我们这里被引用变量的值是用来加到前面的,没有改变其值,所以这个引用符号可以去掉。
那第一个引用符号又是为何呢?为了说明清楚,我们将增加几行代码,让诸位更加看清this的本质(去掉了引用符号,且每次输出age值)
class Person {
public:
Person(int age)
{
this -> age = age;
}
Person PersonAddAge(Person p)
{
this->age += p.age; //把别人的age加到自己上面
//this指向p2的指针,而*this指向的是p2这个对象的本体
cout<< (*this).age<<endl;//
return *this;
}
int age;
};
void test01()
{
Person p1(10);
Person p2(10);
cout<<p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1).age<<endl;//
cout<<"p2的年龄为:"<<p2.age<<endl;
}
int main() {
test01();
system("pause");
return 0;
}
发现不加引用符号,虽然最终结果是40,但是p2的age值只是加了一次,即相当于三次调用函数中只有第一次指向的是原对象p2,其原因是不加引用符号,那么return的结果只是将*this指向的对象复制给一个临时对象,而不是真正的原对象。就好比普通函数中return x,返回的只是x的复制的值。即这里只有第一次函数内部对原对象p2进行了修改,而后面每次调用都是对临时对象操作的。那么如果加上引用符号&之后,就使得每次的临时对象是原对象p2的一个别名,即每次调用函数都改变了原对象p2内的参数。
这才有了老师附的如下完整代码:
class Person
{
public:
Person(int age)
{
//1、当形参和成员变量同名时,可用this指针来区分
this->age = age;//this指针指向被调用的成员函数所属的对象。
}
Person& PersonAddPerson(Person p)
{
this->age += p.age;
//返回对象本身
return *this;
}
int age;
};
void test01()
{
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;
}
int main() {
test01();
system("pause");
return 0;
}
自结:要加引用符号return的才是真正的P2对象本身,否则只是P2的一个copy。即如果没有&,那么后面操作就不会改变P2了
补充:原来老师视频的最后讲了这个哈哈哈哈,我看到一半的时候因为老师直接加了&导致我不理解就自己摸索原理去了,同时写了上面的文章,写完了继续看视频的时候发现老师有讲,原因是:以值的方式返回局部对象会调用拷贝构造函数,从而生成新的匿名变量。和我上面理解的差不多,也就是不加引用的话是p2`,p2``……,总之p2的属性值就不会变了。
其实一句话要想实现这种链式编程,记住加&就行了。