在 C++ 中显式传递 *this

Explicitly passing *this in C++

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

When a nonstatic member function is called for an object, the compiler passes the object's address to the function as a hidden argument.

然后我尝试了:

#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;
}

为什么我无法访问隐藏参数?是不是因为这个才叫'hidden'?

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

我在问这个问题之前找到的最接近的答案是 this。但是我那样试了,还是报错。我能得到这些错误消息的解释吗?因为,如果编译器实际上修改了那些函数签名以包含 *this 那么这应该有效,不是吗?

obj.getVar(&obj)

此版本无法编译,因为 getVar() 成员函数未声明为采用任何参数。

MyClass::getVar(&obj)

此版本使用语法访问 static 函数,但 getVar() 不是 static,也不接受任何参数。

注意: obj.getVar() 调用有效,因为它指定要使用哪个对象实例(即 obj. 部分)来执行成员函数从概念上讲,成员函数是如何 传递 this 指针的

Are only compilers allowed to do this?

没错。这就是它被称为隐藏的原因:它是编译器代表您执行的操作,但对使用它的 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++ 实际翻译您的代码的方式。

当你在做 obj.getVar() 时,它已经明确指定了指针 *this=&obj 并隐式传递得到Var。它没有隐藏。它显式地传递给函数的左侧。您可以使用 obj.getVar() 或 ptrObj->getVar() 但在 C++ 中不允许使用这样的结构 getVar(thisptr)。隐藏意味着变量名为 this 未在任何地方声明,但您可以在函数内部使用。