【C++掌中宝】类和对象(二):隐藏的this指针
文章目录
引言
在 C++ 编程中,类是面向对象编程的核心,而类中的成员函数与对象的交互则通过一个隐含的指针来实现,这就是 this
指针。它在 C++ 类的非静态成员函数中自动存在并指向调用该函数的对象实例。在这篇文章中,我们将详细探讨 this
指针的定义、用法以及其背后的工作原理。
1. 定义与用法
1.1 隐式存在的 this 指针
在 C++ 中,每个非静态成员函数都会隐式包含一个 this
指针,它指向调用该成员函数的对象实例。对于开发者来说,this
指针无需显式声明或传递,它由编译器自动管理。
1.2 this 指针的用途与示例
this
指针最常见的用途是解决成员变量与函数参数同名的问题,此外它还可以用于在成员函数中返回对象本身。例如:
class Person {
public:
Person(int age) {
this->age = age; // 用 this 指针区分成员变量和参数
}
Person& addAge(int age) {
this->age += age;
return *this; // 返回对象本身
}
int age;
};
在上面的代码中,当函数的参数 age
与类的成员变量 age
同名时,我们使用 this->age
来明确表示成员变量。另外,通过 return *this
,我们可以在函数返回时返回调用该函数的对象,从而支持方法链调用。
2. 本质
this
指针的本质是一个常量指针,其类型为 ClassName* const
,指向调用该成员函数的对象实例。它不可修改,即我们无法改变 this
指针指向的对象。
例如,当你调用 obj.SetValue(5)
时,实际上执行的函数是 SetValue(&obj, 5)
。this
指针指向了对象 obj
,从而确保函数操作的是正确的对象。
3. 特点
- 只能在非静态成员函数中使用:全局函数和静态成员函数中都无法使用
this
指针。 - 生命周期与成员函数一致:
this
指针在成员函数调用时被创建,并在函数执行结束时销毁。 - 存储位置因编译器而异:
this
指针可能存储在栈、寄存器或全局变量中,具体取决于编译器的实现。
4. this 指针的作用机制
为了深入理解 this
指针的作用,我们可以将 C++ 代码转换为 C 代码。在 C 语言中,没有类的概念,但我们可以用结构体和全局函数来模拟类和成员函数:
struct Car {
int price;
};
void SetPrice(struct Car* this, int price) {
this->price = price;
}
int main() {
struct Car car;
SetPrice(&car, 20000);
return 0;
}
上面的 C 代码模拟了 C++ 的类机制,其中 SetPrice
函数需要传入 Car
结构体的指针才能访问其成员变量。这就相当于 C++ 中 this
指针的工作方式。
5. 成员函数中的 this 指针
非静态成员函数中默认会包含 this
指针。例如,在成员函数中调用其他成员函数或访问成员变量时,编译器实际上是通过 this
指针来完成的:
class Car {
public:
int price;
void setPrice(int p) {
this->price = p; // this 指向调用该函数的对象
}
};
6. 空指针与 this 指针的特殊情况
在某些极端情况下,this
指针可能为空。例如,当我们通过空指针调用一个没有访问成员变量的成员函数时,程序不会崩溃
class A {
public:
void sayHello() { std::cout << "Hello" << std::endl; }
};
int main() {
A* ptr = nullptr;
ptr->sayHello(); // 输出 "Hello"
}
因为前一篇文章我们说过成员函数地址是编译时确定的,不是存在对象里面的,而是单独存在一个代码段里,所以这里面没有解引用。
然而,如果该成员函数访问了成员变量,程序将崩溃,因为 this
指针为空,指向了非法内存区域。
7. 注意事项
- 静态成员函数无法使用
this
指针,因为它们属于类本身,而不是类的具体实例。因此,静态成员函数无法访问非静态成员变量。 - C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。
8. 总结
this
指针是 C++ 中的一个重要机制,帮助成员函数与对象实例关联。它在类的成员函数内部自动存在,指向调用该函数的对象实例。通过掌握 this
指针的用法,开发者可以更好地理解面向对象编程的原理,并编写更加灵活和健壮的代码。
结语
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。
也可以点点关注,避免以后找不到我哦!
Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!
原文地址:https://blog.csdn.net/2301_80191662/article/details/142650191
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!