介绍C++中this指针
介绍C++中this指针
在C++中,this指针是一个非常重要的概念,它是一个隐式的指针,表示指向正在调用类成员函数的对象的指针。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
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
5Initial 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
5Area 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
4The 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
7Constructor 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
5v1: (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
7Constructor 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
虽然这个例子中没有直接使用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
3Hi, 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指针在成员函数中返回对象的引用,从而实现链式调用。这种方法可以使代码更紧凑,更具可读性。