介绍C++中this指针

介绍C++中this指针

在C++中,this指针是一个非常重要的概念,它是一个隐式的指针,表示指向正在调用类成员函数的对象的指针。this指针在类的成员函数中可以使用,用于引用调用该成员函数的对象。它主要有以下用途:

  1. 区分局部变量和成员变量:当成员函数的局部变量与类的成员变量同名时,可以使用this指针来引用类的成员变量。
  2. 链式调用:在类的成员函数中返回this指针,可以实现链式调用。
  3. 作为友元函数的参数:将this指针作为参数传递给友元函数,可以让友元函数访问当前对象的成员。

以下是一个简单的示例,说明this指针的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

class MyClass {
private:
int x;

public:
MyClass(int x) : x(x) {}

// 使用this指针区分成员变量和局部变量
void setX(int x) {
this->x = x;
}

int getX() const {
return x;
}

// 使用this指针实现链式调用
MyClass& increment() {
++x;
return *this;
}

// 声明友元函数
friend void printX(const MyClass* obj);
};

// 使用this指针作为参数的友元函数
void printX(const MyClass* obj) {
std::cout << "x = " << obj->x << std::endl;
}

int main() {
MyClass obj(5);

std::cout << "Initial value: " << obj.getX() << std::endl;

obj.setX(10);
std::cout << "After setX: " << obj.getX() << std::endl;

obj.increment().increment().increment();
std::cout << "After increment chain: " << obj.getX() << std::endl;

printX(&obj);

return 0;
}

输出:

1
2
3
4
5
Initial value: 5
After setX: 10
After increment chain: 13
x = 13


在这个例子中,我们展示了this指针在成员函数中如何用于区分成员变量和局部变量,实现链式调用,以及作为参数传递给友元函数。

接下来,我们通过另一个示例来介绍this指针在C++中的其他用途。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>

class Rectangle {
private:
double width;
double height;

public:
Rectangle(double width, double height) : width(width), height(height) {}

// 使用this指针实现方法的重载
Rectangle& setWidth(double width) {
this->width = width;
return *this;
}

Rectangle& setHeight(double height) {
this->height = height;
return *this;
}

double getWidth() const {
return width;
}

double getHeight() const {
return height;
}

double getArea() const {
return width * height;
}

// 使用this指针实现比较操作
bool isBiggerThan(const Rectangle& other) const {
return this->getArea() > other.getArea();
}

// 使用this指针实现拷贝赋值操作符重载
Rectangle& operator=(const Rectangle& other) {
if (this == &other) {
return *this;
}

this->width = other.width;
this->height = other.height;

return *this;
}
};

int main() {
Rectangle r1(4, 5);
Rectangle r2(6, 7);

std::cout << "Area of r1: " << r1.getArea() << std::endl;
std::cout << "Area of r2: " << r2.getArea() << std::endl;

if (r1.isBiggerThan(r2)) {
std::cout << "r1 is bigger than r2" << std::endl;
} else {
std::cout << "r1 is smaller than or equal to r2" << std::endl;
}

r1 = r2;
std::cout << "After assignment, area of r1: " << r1.getArea() << std::endl;

return 0;
}


输出:
1
2
3
4
5
Area of r1: 20
Area of r2: 42
r1 is smaller than or equal to r2
After assignment, area of r1: 42


在这个例子中,我们展示了this指针在实现方法重载、比较操作、以及拷贝赋值操作符重载时的使用。通过使用this指针,我们可以让代码更易读且功能更强大。

在此示例中,我们将进一步探讨this指针在类的继承和多态中的应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <memory>

class Animal {
public:
virtual void makeSound() const {
std::cout << "The animal makes a generic sound." << std::endl;
}

// 使用this指针实现运行时多态
Animal* getThis() {
return this;
}
};

class Dog : public Animal {
public:
void makeSound() const override {
std::cout << "The dog barks: Woof!" << std::endl;
}
};

class Cat : public Animal {
public:
void makeSound() const override {
std::cout << "The cat meows: Meow!" << std::endl;
}
};

void playWithAnimal(Animal* animal) {
animal->makeSound();
}

int main() {
std::unique_ptr<Animal> dog = std::make_unique<Dog>();
std::unique_ptr<Animal> cat = std::make_unique<Cat>();

playWithAnimal(dog.get());
playWithAnimal(cat.get());

Animal* polymorphicAnimal = dog->getThis();
polymorphicAnimal->makeSound();

return 0;
}


输出:
1
2
3
4
The dog barks: Woof!
The cat meows: Meow!
The dog barks: Woof!


在这个例子中,我们创建了一个Animal基类,以及两个派生类Dog和Cat。我们重写了基类的makeSound方法,以实现多态行为。通过使用this指针,我们可以在运行时获取多态对象的实际类型,从而调用相应的方法。

当我们使用this指针调用getThis()方法时,返回的是一个指向当前对象的指针。由于getThis()方法返回的是Animal*类型的指针,this指针在这里发挥了运行时多态的作用。这允许我们在运行时确定调用哪个类的makeSound方法。在这个例子中,polymorphicAnimal->makeSound();将调用Dog类的makeSound方法,因为polymorphicAnimal指针指向的实际对象类型是Dog。

这个例子展示了this指针在类继承和运行时多态中的应用,帮助我们更好地理解C++面向对象编程的概念。

接下来,我们将通过一个实例来了解this指针在构造函数和析构函数中的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

class MyClass {
private:
int id;

public:
static int objectCount;

MyClass() {
id = ++objectCount;
std::cout << "Constructor called for object ID: " << id << std::endl;
}

~MyClass() {
std::cout << "Destructor called for object ID: " << id << std::endl;
}

// 返回this指针以进行比较
const MyClass* getThis() const {
return this;
}

bool isEqual(const MyClass* other) const {
return this == other;
}
};

int MyClass::objectCount = 0;

int main() {
MyClass obj1;
MyClass obj2;

if (obj1.getThis() == obj2.getThis()) {
std::cout << "obj1 and obj2 are the same object." << std::endl;
} else {
std::cout << "obj1 and obj2 are different objects." << std::endl;
}

if (obj1.isEqual(&obj2)) {
std::cout << "obj1 is equal to obj2." << std::endl;
} else {
std::cout << "obj1 is not equal to obj2." << std::endl;
}

return 0;
}


输出:
1
2
3
4
5
6
7
Constructor called for object ID: 1
Constructor called for object ID: 2
obj1 and obj2 are different objects.
obj1 is not equal to obj2.
Destructor called for object ID: 2
Destructor called for object ID: 1


在这个例子中,我们创建了一个MyClass类,并在构造函数中为每个对象分配了一个唯一的ID。通过使用this指针,我们可以在析构函数中访问对象的ID,以便在对象被销毁时输出相应的信息。

同时,我们还实现了getThis()方法,该方法返回一个指向当前对象的指针。我们可以通过比较两个对象的this指针来判断它们是否是同一个对象。此外,我们还实现了一个isEqual()方法,用于比较两个对象的this指针,以确定它们是否相等。

这个例子展示了this指针在构造函数和析构函数中的用途,以及如何通过比较this指针来判断两个对象是否相等。

在这个例子中,我们将探讨如何在类模板中使用this指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>

template <typename T>
class MyVector {
private:
T x, y, z;

public:
MyVector(T x, T y, T z) : x(x), y(y), z(z) {}

// 使用this指针实现输出操作符重载
friend std::ostream& operator<<(std::ostream& os, const MyVector& v) {
os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
return os;
}

// 使用this指针实现加法操作符重载
MyVector operator+(const MyVector& other) const {
return MyVector(this->x + other.x, this->y + other.y, this->z + other.z);
}

// 使用this指针实现赋值操作符重载
MyVector& operator+=(const MyVector& other) {
this->x += other.x;
this->y += other.y;
this->z += other.z;
return *this;
}
};

int main() {
MyVector<int> v1(1, 2, 3);
MyVector<int> v2(4, 5, 6);

std::cout << "v1: " << v1 << std::endl;
std::cout << "v2: " << v2 << std::endl;

MyVector<int> v3 = v1 + v2;
std::cout << "v3 (v1 + v2): " << v3 << std::endl;

v1 += v2;
std::cout << "v1 after (v1 += v2): " << v1 << std::endl;

return 0;
}


输出:
1
2
3
4
5
v1: (1, 2, 3)
v2: (4, 5, 6)
v3 (v1 + v2): (5, 7, 9)
v1 after (v1 += v2): (5, 7, 9)


在这个例子中,我们创建了一个类模板MyVector,用于表示一个三维向量。我们在类模板中使用this指针实现了输出操作符重载、加法操作符重载和赋值操作符重载。

通过使用this指针,我们可以访问当前对象的成员变量,并返回当前对象的引用。这在实现类模板中的操作符重载时非常有用,因为我们可以轻松地访问和修改当前对象的状态

这个例子展示了this指针在类模板中的应用,以及如何通过this指针实现操作符重载。

在这个示例中,我们将探讨如何在智能指针中使用this指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <memory>

class MyClass {
public:
int value;

MyClass(int v) : value(v) {
std::cout << "Constructor called: " << value << std::endl;
}

~MyClass() {
std::cout << "Destructor called: " << value << std::endl;
}

void printValue() const {
std::cout << "Value: " << value << std::endl;
}

// 使用this指针实现工厂方法,创建shared_ptr对象
static std::shared_ptr<MyClass> create(int value) {
return std::shared_ptr<MyClass>(new MyClass(value));
}
};

void processObject(std::shared_ptr<MyClass> obj) {
obj->printValue();
}

int main() {
std::shared_ptr<MyClass> obj1 = MyClass::create(5);
processObject(obj1);

std::shared_ptr<MyClass> obj2 = MyClass::create(10);
processObject(obj2);

return 0;
}


输出:
1
2
3
4
5
6
7
Constructor called: 5
Value: 5
Constructor called: 10
Value: 10
Destructor called: 10
Destructor called: 5


在这个例子中,我们创建了一个MyClass类,该类包含一个静态方法create,用于创建MyClass对象的std::shared_ptr智能指针。在create方法中,我们使用new操作符分配一个新的MyClass对象,并将其传递给std::shared_ptr构造函数。这样,当std::shared_ptr对象超出作用域时,会自动调用MyClass对象的析构函数并释放内存。

我们还实现了一个processObject函数,该函数接受一个std::shared_ptr参数,并在其中调用printValue方法。通过使用智能指针,我们可以确保资源在不再使用时被正确释放,避免内存泄漏。

虽然这个例子中没有直接使用this指针,但它演示了如何使用智能指针来管理类实例的生命周期。智能指针可以与this指针一起使用,以确保在操作类对象时始终遵循良好的内存管理实践。

在本示例中,我们将研究如何使用this指针在成员函数中返回自身的引用以支持链式调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>

class Person {
private:
std::string name;
int age;

public:
Person(const std::string& name, int age) : name(name), age(age) {}

Person& setName(const std::string& newName) {
name = newName;
return *this;
}

Person& setAge(int newAge) {
age = newAge;
return *this;
}

void introduce() const {
std::cout << "Hi, my name is " << name << " and I am " << age << " years old." << std::endl;
}
};

int main() {
Person alice("Alice", 28);
alice.introduce();

alice.setName("Alicia").setAge(29);
alice.introduce();

return 0;
}


输出:
1
2
3
Hi, my name is Alice and I am 28 years old.
Hi, my name is Alicia and I am 29 years old.


在此示例中,我们创建了一个名为Person的类,其中包含两个成员函数setName和setAge,这两个函数返回当前对象的引用(通过*this)。这允许我们实现链式调用,即在单个语句中连续调用多个成员函数。

在main函数中,我们首先创建了一个名为alice的Person对象,并调用introduce方法。然后,我们使用链式调用来同时设置alice的新名称和年龄,再次调用introduce方法以查看更改是否生效。

这个例子展示了如何使用this指针在成员函数中返回对象的引用,从而实现链式调用。这种方法可以使代码更紧凑,更具可读性。


介绍C++中this指针
https://qiangsun89.github.io/2023/05/04/介绍C-中this指针/
作者
Qiang Sun
发布于
2023年5月4日
许可协议