迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

在 C++ 中使用 this 指针

作者:迹忆客 最近更新:2023/03/15 浏览次数:

在本文中,我们将首先了解 this 指针的概念。

然后,我们将借助示例演示其用途。最后,我们将看到 this*this 有何不同。

在 C++ 中使用 this 指针

this 指针只是一个隐式可用指针,在非静态类成员函数范围内,它引用或指向调用对象。如果你没有通过定义得到它,那么让我们看一些基础知识来理解这个概念。

我们知道所有非静态数据成员对每个对象都有一个单独的副本。但是,成员函数代码在所有对象之间共享。

同一类的所有对象在需要调用时都从代码段访问相同的函数定义。编译器需要知道调用对象(当前调用成员函数的对象)信息以访问或更新特定于该特定调用对象的正确数据成员。

那么,在函数定义相同的情况下,编译器如何获取调用对象信息呢?

简单的回答是,在程序的编译过程中,编译器会自动在成员函数中添加一个隐藏的隐式指针参数。这个隐式指针被称为 this 指针。

每当通过特定类对象调用成员函数时,调用对象会自动作为隐藏参数提供给 this 指针。现在,编译器可以使用这个指针来访问或修改特定于调用对象的正确数据成员。

对静态成员的更新或访问并不特定于任何对象。我们甚至可以在不创建类对象的情况下访问这些成员。

因此,编译器不会对这些成员使用 this 运算符。

让我们看一下代码示例,以了解为什么我们说编译器隐式使用 this 指针以及何时使用它很方便。

#include <iostream>
#include <string>
using namespace std;

class Person{
private:
    string Name;
public:
    Person(string Name) {
        this->Name = Name; //this->Name is the private member for this object
    }
    void PrintName() {
        cout<<this->Name<<endl;
    }
    void PrintName1() {
        cout<<Name<<endl;
    }
};
int main()
{
    Person P("Alexa");
    P.PrintName();
    P.PrintName1();
    return 0;
}

上面的代码示例定义了一个具有两个不同成员函数的 Person 类来打印私有数据成员 Namemain() 函数中的第一条语句生成一个 Person 对象并将 Alexa 作为参数传递给构造函数。

现在,构造函数中的 this->Name 帮助编译器区分本地参数 Name 和私有数据成员 Name

main() 的后续代码通过 P 调用 printName()printName1()(即 P 成为调用者对象)。

输出:

Alexa
Alexa

两个函数的输出是一样的。这是因为编译器在 PrintName1() 中隐含地在 this-> 前面加上 Name

C++ 中 this*this 的区别

到目前为止,我们已经清楚 this 是指向对象的指针的概念。对于 Person 类型的 objthisPerson*类型。

要记住的另一件事是 this 指针始终是一个 rvalue,不能修改。然而,*this 取消引用 this 指针。

在经历了足够的背景之后,让我们看一个示例代码来了解 this*this 之间的区别。

#include <iostream>
using namespace std;

class Counter {
private:
    int Count;
public:
    Counter() { this->Count = 0; }
    void IncreaseCount() { Count++; }
    void PrintCount() { cout << this->Count << endl; }
    Counter* GetCount_Pointer() { return this; }
    Counter GetCount_Copy() { return *this; }
    Counter& GetCount_Reference() { return *this; }

};
int main()
{
    //Section-A
    cout << "Sectio-A" << endl;
    Counter C1;
    C1.IncreaseCount();
    Counter* CounterPtr = C1.GetCount_Pointer(); //CounterObj will be pointing to C1
    CounterPtr->IncreaseCount();
    C1.PrintCount();

    //Section-B
    cout << "Section-B" << endl;
    Counter C2;
    C2 = C1.GetCount_Copy();
    C1.IncreaseCount();
    C1.PrintCount();
    C2.PrintCount();

    //Section-C
    cout << "Section-B" << endl;
    Counter& CounterRef = C1.GetCount_Reference();
    CounterRef.PrintCount();

    return 0;
}

此代码片段创建了一个 Counter 类,其中包含多个 GetCount 方法的方法。第一个方法(即 GetCount_Pointer)返回 this 指针的值,它只是调用对象的地址。

GetCount_Copy 方法返回 *this 而返回类型是 Counter 类型的对象。因此,此函数将返回调用对象的深层副本,这意味着修改返回的副本不会影响原始副本。

最后一个 GetCount_Reference 方法也返回 *this,但此方法的返回类型是一个引用对象(即 Counter&)。编译器不会创建新的深层副本,而是返回对原始对象的别名或引用。

通过别名所做的任何更改也将反映在原始对象中。

在讨论主驱动代码之前,让我们看一下程序的输出。

输出:

Sectio-A
2
Section-B
3
2
Section-B
3

main 方法的 A 部分首先声明 Counter 类型的 C1 对象并通过 IncreaseCount() 递增其 Count。稍后,它用 C1.GetCount_Pointer() 返回的地址初始化一个 CounterPtr 指针。

现在,CounterPtr 将指向 C1。因此,通过 CounterPtr 调用增量函数也会修改 C1

B 部分中的 C2 = C1.GetCount_Copy()C1 的所有当前内容深度复制到 C2,因为 C1.GetCount_Copy()C1 的副本替换。因此,增加 C1 的计数不会影响 C2

C 部分声明了一个 Counter 类型的引用变量,并使用 C1.GetCount_Reference() 返回的任何内容对其进行初始化。由于 C1.GetCount_Reference() 返回 C1 的别名,因此 CounterRef 成为 C1 的另一个名称。

语句 Counter& CounterRef = C1.GetCount_Reference(); 逻辑上等价于 Counter& CounterRef = C1

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C++ 中通过掷骰子生成随机值

发布时间:2023/04/09 浏览次数:169 分类:C++

本文解释了如何使用时间因子方法和模拟 C++ 中的掷骰子的任意数方法生成随机数。了解它是如何工作的以及它包含哪些缺点。提供了一个 C++ 程序来演示伪数生成器。

在 C++ 中使用模板的链表

发布时间:2023/04/09 浏览次数:158 分类:C++

本文解释了使用模板在 C++ 中创建链表所涉及的各个步骤。工作程序演示了一个链表,该链表使用模板来避免在创建新变量时声明数据类型的需要。

在 C++ 中添加定时延迟

发布时间:2023/04/09 浏览次数:142 分类:C++

本教程将为你提供有关在 C++ 程序中添加定时延迟的简要指南。这可以使用 C++ 库为我们提供的一些函数以多种方式完成。

在 C++ 中创建查找表

发布时间:2023/04/09 浏览次数:155 分类:C++

本文重点介绍如何创建查找表及其在不同场景中的用途。提供了三个代码示例以使理解更容易,并附有代码片段以详细了解代码。

如何在 C++ 中把字符串转换为小写

发布时间:2023/04/09 浏览次数:63 分类:C++

介绍了如何将 C++ std::string 转换为小写的方法。当我们在考虑 C++ 中的字符串转换方法时,首先要问自己的是我的输入字符串有什么样的编码

如何在 C++ 中确定一个字符串是否是数字

发布时间:2023/04/09 浏览次数:163 分类:C++

本文介绍了如何检查给定的 C++ 字符串是否是数字。在我们深入研究之前,需要注意的是,以下方法只与单字节字符串和十进制整数兼容。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便