首页 > 解决方案 > 在 C++ 中显式传递 *this

问题描述

在阅读有关*this时,我看到:

当为对象调用非静态成员函数时,编译器会将对象的地址作为隐藏参数传递给函数。

然后我尝试了:

#include <iostream>

class MyClass
{
    int myVar;
public:
    MyClass(const int& val) : myVar{val} {}
    // int getVar(MyClass* this) <-- Error: expected ',' or '...' before 'this'
    int getVar()
    {
        return this->myVar;
    }
};

int main()
{
    MyClass obj(22);
    // std::cout << obj.getVar(&obj);      <-- Error: no matching function
    // std::cout << MyClass::getVar(&obj); <-- Error: no matching function
    std::cout << obj.getVar();
    return 0;
}

为什么我无法访问隐藏的参数?是否因此而被称为“隐藏”?

只有编译器允许这样做吗?我们不能*this在函数签名中明确提及吗?

在问这个之前我找到的最接近的答案是this。但是我尝试了这种方式,但仍然出现错误。我能得到这些错误信息的解释吗?因为,如果编译器实际上修改了这些函数签名以包含*this,那么这应该可以工作,不是吗?

标签: c++classobjectthismember-functions

解决方案


只有编译器允许这样做吗?

恰恰。这就是它被称为隐藏的原因:这是编译器代表您执行的操作,但对使用它的 C++ 代码是隐藏的。

编译器必须this以某种方式将指针传递给成员函数,但它不需要告诉您它是如何做到的。它可以将代码编译为等价于MyClass::getVar(&obj),传递this指针的方式与传递 C 函数的参数的方式相同free(foo)。或者它可能使用与非成员参数传递完全不兼容的不同机制。它的底层功能由平台的抽象二进制接口标准 (ABI) 定义,该标准不是 C++ 语言标准的一部分。Windows 下发生的情况可能与 Linux 下发生的情况大不相同,ARM 上的 Linux 可能与 X86 上的 Linux 不同,等等。

也就是说,您可以通过告诉编译器生成汇编代码来查看实际发生的情况。因为gcc,咒语是

g++ -S -Os interestingCode.cpp

这将生成一个.s文件,其中包含g++实际翻译代码的方式。


推荐阅读