Pur*_*ima 30 c++ class this-pointer
正如标题中所提到的,我想知道'this'指针的类型.
我正在研究一个项目,我发现'this'指针的类型是"ClassName * const this"在使用VC++ 2008的Windows上.我想知道是什么需要/要求使这个指针成为一个常量指针.谢谢.
AnT*_*AnT 47
该指针的类型是ClassName *或者const ClassName *,取决于它是否在类的非const或const方法中进行检查ClassName.指针this不是左值.
class ClassName {
void foo() {
// here `this` has `ClassName *` type
}
void bar() const {
// here `this` has `const ClassName *` type
}
};
Run Code Online (Sandbox Code Playgroud)
您在上面提到的观察结果具有误导性.指针this是不是左值,这意味着它不可能有ClassName * const类型的,即它不能可能具有const到的右侧*.指针类型的非左值不能是const或非const.在C++语言中根本没有这样的概念.你观察到的必须是特定编译器的内部怪癖.形式上,它是不正确的.
以下是语言规范中的相关引用(强调我的)
9.3.2这个指针
在非静态(9.3)成员函数的主体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址.类X的成员函数中的类型是X*.如果成员函数声明为const,则其类型为const X*,如果成员函数声明为volatile,则其类型为volatile X*,如果成员函数声明为const volatile,则此类型为const挥发性X*.[注意:因此在const成员函数中,调用函数的对象是通过const访问路径访问的. - 尾注]
在C++ 98/C++ 03中,几个编译器使用内部实现技巧是值得的:它们将它们的this指针解释为常量指针,例如ClassName *const在非常量类方法中ClassName.这显然帮助他们确保了不可修改性this.已知GCC和MSVC已经使用该技术.这是一个无害的伎俩,因为在语言层面this上并不是左值,而且它的常数是不可检测的.该额外const通常仅在编译器发出的诊断消息中显示出来.
但是,随着C++ 11中rvalue引用的出现,有可能const在类型上检测到这个额外的this.例如,以下代码在C++ 11中有效
struct S
{
void foo() { S *&&r = this; }
};
Run Code Online (Sandbox Code Playgroud)
然而,它通常无法在仍然使用上述技巧的实现中进行编译.GCC此后放弃了该技术.MSVC++仍然使用它(自VS2017起),这阻止了上述完全有效的代码在MSVC++中进行编译.