在 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 未在任何地方声明,但您可以在函数内部使用。
在阅读有关 *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 未在任何地方声明,但您可以在函数内部使用。