返回项目列表

/note/ICPC笔记

ICPC笔记

当前项目读取 content/notes/ICPC笔记 下的 Markdown 文件。

ICPC笔记

this指针

this指针 this 就是“当前正在调用成员函数的那个对象”的地址。 比如: 如果你写: 那么在 show() 函数里面,this 指向的就是对象 a。 1. this 是什么? 在 C++ 里,每个 非静态成员函数 内部都有一个隐藏的指针,叫 this。 例如: 表面上你写的是: 但编译器大概会...

this指针

this 就是“当前正在调用成员函数的那个对象”的地址。

比如:

class Student {
private:
    string name;
    int age;

public:
    void show() {
        cout << name << " " << age << endl;
    }
};

如果你写:

Student a;
a.show();

那么在 show() 函数里面,this 指向的就是对象 a


1. this 是什么?

在 C++ 里,每个 非静态成员函数 内部都有一个隐藏的指针,叫 this

例如:

class Student {
private:
    int age;

public:
    void setAge(int x) {
        age = x;
    }
};

表面上你写的是:

s.setAge(18);

但编译器大概会理解成类似这样:

Student::setAge(&s, 18);

也就是说,成员函数背后偷偷多传了一个参数:当前对象的地址。

所以在 setAge 里面:

this

就是当前对象的地址。

this->age

就是当前对象的 age 成员。


2. this->成员变量

来看一个最经典的场景:

class Student {
private:
    string name;
    int age;

public:
    Student(string name, int age) {
        this->name = name;
        this->age = age;
    }
};

这里为什么要写 this->name

因为构造函数参数也叫 name,成员变量也叫 name

Student(string name, int age)

里面的 name 默认优先指的是参数,不是成员变量。

所以:

name = name;

这是参数自己赋值给自己,没意义。

正确写法:

this->name = name;
this->age = age;

意思是:

当前对象的 name = 参数 name;
当前对象的 age = 参数 age;

3. this 是一个指针

既然 this 是指针,那么它保存的是对象地址。

class A {
public:
    void printThis() {
        cout << this << endl;
    }
};

使用:

A a;
a.printThis();
cout << &a << endl;

这两个输出的地址是一样的。

因为:

this == &a

4. *this 是当前对象本身

既然:

this

是当前对象的地址,那么:

*this

就是当前对象本身。

这在运算符重载和链式调用里面特别常见。

比如:

class Counter {
private:
    int x;

public:
    Counter(int x = 0) {
        this->x = x;
    }

    Counter& add(int n) {
        x += n;
        return *this;
    }

    void show() {
        cout << x << endl;
    }
};

使用:

Counter c;
c.add(1).add(2).add(3);
c.show();

输出:

6

为什么能连续调用?

因为:

add()

返回的是:

*this

也就是当前对象本身的引用。

所以:

c.add(1).add(2).add(3);

相当于:

c 加 1 后,还是返回 c;
再给 c 加 2;
再给 c 加 3;

5. return *this 常用于返回当前对象引用

operator+=、前置 ++,里面经常会看到这个:

ClockTime& operator+=(int x) {
    minute += x;
    tolegal();
    return *this;
}

这句话的意思是:

返回当前对象本身

为什么返回类型是引用?

ClockTime&

因为我们不想复制一个新对象,而是返回原对象自己。

例如:

a += 10 += 20; // 这种写法不常见

更常见的是:

(a += 10) += 20;

如果 operator+= 返回引用,那么后面还能继续对原对象操作。


6. thisconst 成员函数

你经常看到:

int getAge() const {
    return age;
}

这个 const 修饰的是谁?

它本质上修饰的是 this

普通成员函数中,this 类型大概是:

Student* const this

意思是:this 本身不能改指向,但可以通过它修改对象内容。

而在 const 成员函数中,this 类型大概是:

const Student* const this

意思是:不能通过 this 修改当前对象。

所以:

class Student {
private:
    int age;

public:
    int getAge() const {
        return age;
    }

    void setAge(int x) {
        age = x;
    }
};

getAge() const 里面不能写:

age = 18;

因为它相当于:

this->age = 18;

但是 this 是指向 const 对象的指针,不允许修改对象。


7. const 对象只能调用 const 成员函数

比如:

class Student {
private:
    int age;

public:
    int getAge() const {
        return age;
    }

    void setAge(int x) {
        age = x;
    }
};

如果有:

const Student s;

那么可以:

s.getAge();

但不能:

s.setAge(18);

因为 sconst 对象,不能被修改。

setAge() 不是 const 成员函数,理论上可能修改对象,所以不能调用。

这和 this 有关系:

const Student s;

调用成员函数时,传进去的 this 是:

const Student*

所以只能匹配:

int getAge() const

不能匹配:

void setAge(int x)

8. this 不能在静态成员函数里用

比如:

class A {
public:
    static void f() {
        cout << this << endl; // 错误
    }
};

为什么错误?

因为 static 成员函数不属于某一个具体对象。

它是属于整个类的。

比如:

A::f();

你直接用类名就能调用它,根本没有对象。

没有对象,就没有“当前对象”,也就没有 this

所以:

静态成员函数里面没有 this 指针。