'this'指针的类型

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++中进行编译.

  • @Purnima:不.这意味着你的"C++ Primer 4th ed"不正确.我不知道这是故意的错误(为了简化)还是书中的真正错误,但是说'this`是一个"const指针"总是不正确的.同样,`this`是标量类型的右值.标量类型的Rvalues不能是const或非const.第四版于2001年出版,意味着它相当陈旧.检查以后的版本可能是有意义的.错误可能会在那里修复. (2认同)