RaymondHuang
RaymondHuang
发布于 2022-12-17 / 71 阅读
0
0

类中的this指针

在构造函数中,如果传进来的形参名字和成员名字一样,需要用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的创建,都是调用了拷贝构造函数


评论