在构造函数中,如果传进来的形参名字和成员名字一样,需要用this指针区分,否则无法赋值:
class Student {
public:
int id;
Student(int id) {
this->id = id; // 如果直接写成id = id,那么最终id还是0,即没有被赋值!
}
}
this指针,就是谁调用,指向的就是谁,比如:
Student s1(10);
在构造函数中,this指向的就是s1,所以,就是给s1的id成员赋值。
当然,最重要的是,this指针可是用来实现连锁调用:
class Student {
public:
int id;
Student(int id) {
this->id = id;
}
Student& id_plus1(Student& s) { // 连锁调用函数
id += s.id;
return *this;
}
}
int main() {
Student s1(10);
Student s2(0);
s2.id_plus(s1).id_plus(s1);
cout << s2.id << endl;
}
上述结果输出为20,即让0加了两次0。在连锁调用函数中,函数返回了一个引用,传入的也是一个引用(注意,如果传入的不是引用,那会调用拷贝构造函数,但不影响结果)。由于返回的是一个引用,可以理解为还是s2自己,那么仍然可以继续调用,因此,实现了连锁调用。
当然,返回的不是引用也没有问题,返回一个指针也是可以的:
// 假设上述Student类中增加一个方法:
Student* id_plus2(Student& s) {
id += s.id;
return this; // 返回的就是传入的对象的指针了,而不是对象本身
}
// 然后再main函数里面这样写:
Student s1(10);
Student s2(0);
s2.id_plus2(s1)->id_plus2(s1);
cout << s2.id << endl;
// 或者写成:
Student s1(10);
Student* s2 = new Student(0);
s2->id_plus2(s1)->id_plus2(s1);
cout << s2->id << endl;
上述输出的结果还是20,但原理不同,可以看到在连锁调用的时候,那个调用的”.“变成了”->“,就是因为第一次调用之后,返回的是一个指针,所以第二次调用的时候就要用箭头了。
值得注意的是,如果函数返回的既不是引用,也不是指针,那就有点意思了:
// 假设上述Student类中增加一个方法:
Student id_plus3(Student& s) {
id += s.id;
return *this;
}
// 然后再main函数里面这样写:
Student s1(10);
Student s2(0);
s2.id_plus3(s1).id_plus3(s1).id_plus3(s1);
cout << s2.id << endl;
上述的输出结果是10,无论再连锁调用多少次id_plus3(s1),结果依然是10,因为每次返回来的对象,都可以理解为一个新创建的对象,那么,往后每次创建的对象,都是那个上次被新建的对象加10,而不是原来的s2加10,即等价于:
Student s1(10);
Student s2(0);
Student s3 = s2.id_plus3(s1);
Student s4 = s3.id_plus3(s3);
Student s5 = s3.id_plus3(s4);
cout << s2.id << endl;
那么,真正作用于s2的加10,只有第一次!值得注意的是,s3-s5的创建,都是调用了拷贝构造函数!