【C++掌中宝】类和对象(二):隐藏的this指针

server/2024/10/19 23:46:55/

在这里插入图片描述

文章目录

  • 引言
  • 1. 定义与用法
    • 1.1 隐式存在的 this 指针
    • 1.2 this 指针的用途与示例
  • 2. 本质
  • 3. 特点
  • 4. this 指针的作用机制
  • 5. 成员函数中的 this 指针
  • 6. 空指针与 this 指针的特殊情况
  • 7. 注意事项
  • 8. 总结
  • 结语

引言

在 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. 特点

  1. 只能在非静态成员函数中使用:全局函数和静态成员函数中都无法使用 this 指针。
  2. 生命周期与成员函数一致this 指针在成员函数调用时被创建,并在函数执行结束时销毁。
  3. 存储位置因编译器而异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主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!
在这里插入图片描述


http://www.ppmy.cn/server/126456.html

相关文章

解决方案:机器学习中,出现欠拟合和过拟合,这两种情况分别如何解决

文章目录 一、现象二、解决方案欠拟合&#xff08;Underfitting&#xff09;过拟合&#xff08;Overfitting&#xff09; 一、现象 在工作中&#xff0c;在机器学习中&#xff0c;出现欠拟合和过拟合的时候&#xff0c;需要有对应的解决方法&#xff0c;所以整理一下 二、解决…

【C#生态园】打造现代化跨平台应用:深度解析.NET桌面应用工具

选择最适合你的.NET UI框架&#xff1a;全面解析六种热门选择 前言 在现代软件开发中&#xff0c;选择合适的桌面应用框架和UI库对于开发人员来说至关重要。本文将介绍几种流行的.NET桌面应用框架和UI库&#xff0c;包括Eto.Forms、Avalonia、ReactiveUI、MahApps.Metro、Mat…

OJ在线评测系统 后端 使用代理模式编写测试类 并 实现核心业务判题流程

编写测试类(代理模式) 实现示例的代码沙箱 package com.dduo.dduoj.judge.codesandbox.impl;import com.dduo.dduoj.judge.codesandbox.CodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.Exec…

基于单片机电容测量仪仿真设计

文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…

Redis 实现分布式锁时需要考虑的问题

引言 分布式系统中的多个节点经常需要对共享资源进行并发访问&#xff0c;若没有有效的协调机制&#xff0c;可能会导致数据竞争、资源冲突等问题。分布式锁应运而生&#xff0c;它是一种保证在分布式环境中多个节点可以安全地访问共享资源的机制。而在Redis中&#xff0c;使用…

Pytorch基本知识

model.state_dict()、model.parameters()和model.named_parameters()的区别 parameters()只包含模块的参数,即weight和bias(包括BN的)。 named_parameters()返回包含模块名和模块的参数的列表,列表的每个元素均是包含layer name和layer param的元组。layer param就是param…

根据给定的相机和镜头参数,估算相机的内参。

1. 相机分辨率和传感器尺寸 最高分辨率&#xff1a;6000 4000 像素传感器尺寸&#xff1a;22.3 mm 14.9 mm 2. 计算像素大小 需要计算每个像素对应的实际尺寸&#xff08;mm/pixel&#xff09;&#xff1a; 水平方向像素大小&#xff1a; 垂直方向像素大小&#xff1a; …

Goland使用SSH远程Linux进行断点调试 (兼容私有库)

① 前置需求 ssh远程的 Linux 服务器必须安装 高于本地的 Go推荐golang 安装方式使用 apt yum snap 等系统自管理方式&#xff0c;&#xff08;要安装最新版本的可以找找第三方源&#xff09;&#xff0c;如无特殊需求不要自行编译安装golang ② Goland设置 2.1、设置项处理…