“this"指针的类型

2021-12-09 00:00:00 class c++ this-pointer

如标题所述,我想知道'this'指针的类型.

As mentioned in the title, I would like to know about the type of 'this' pointer.

我正在处理一个项目,我观察到 'this' 指针的类型是 "ClassName * const this" 在使用 VC++ 2008 的 Windows 上.好吧,我想知道使 this 指针成为常量指针的需要/要求是什么.谢谢.

I'm working on a project and I observed that the type of 'this' pointer is "ClassName * const this" on windows using VC++ 2008. Well I would want to know what is the need/requirement to make the this pointer a constant pointer. Thanks.

推荐答案

这个指针的类型是 ClassName * 或者 const ClassName * ,取决于它是否是在 ClassName 类的非常量或常量方法中检查.指针 this 不是左值.

The type of this pointer is either ClassName * or const ClassName *, depending on whether it is inspected inside a non-const or const method of the class ClassName. Pointer this is not an lvalue.

class ClassName {
  void foo() {
    // here `this` has `ClassName *` type
  }

  void bar() const {
    // here `this` has `const ClassName *` type
  }
};

您上面提到的观察具有误导性.指针this 是不是左值,这意味着它不可能有ClassName * const 类型,即它不可能有const* 的右边.指针类型的非左值不能是 const 或非常量.C++ 语言中根本没有这样的概念.您观察到的必须是特定编译器的内部怪癖.形式上,这是不正确的.

The observation you mentioned above is misleading. Pointer this is not an lvalue, which means that it cannot possibly have ClassName * const type, i.e. it cannot possible have a const to the right of the *. Non-lvalues of pointer type cannot be const or non-const. There's simply no such concept in C++ language. What you observed must be an internal quirk of the specific compiler. Formally, it is incorrect.

这里是语言规范中的相关引用(重点是我的)

Here are the relevant quotes from the language specification (emphasis mine)

9.3.2 this 指针

在非静态(9.3)成员函数体中,关键字 this 是一个纯右值表达式,其值为对象的地址该函数被调用.成员函数中this的类型X 类是 X*.如果成员函数被声明为 const,则类型这是 const X*,如果成员函数被声明为 volatile,则this 的类型是 volatile X*,并且如果声明了成员函数const volatile,this 的类型是 const volatile X*. [ 注意:因此在const 成员函数,调用该函数的对象通过 const 访问路径访问.――结尾说明]

In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*. [ Note: thus in a const member function, the object for which the function is called is accessed through a const access path. ―end note ]

<小时>

在 C++98/C++03 时代,一些编译器使用内部实现技巧是毫无价值的:他们将他们的 this 指针解释为常量指针,例如ClassName *const 在类 ClassName 的非常量方法中.这显然有助于他们确保 this 的不可修改性.众所周知,GCC 和 MSVC 已经使用了该技术.这是一个无害的技巧,因为在语言级别 this 不是左值,并且它的常量是不可检测的.额外的 const 通常只会在编译器发出的诊断消息中显示出来.


It is worth nothing that back in the C++98/C++03 times several compilers used an internal implementational trick: they interpreted their this pointers as constant pointers, e.g. ClassName *const in a non-constant method of class ClassName. This apparently helped them to ensure non-modifiablity of this. GCC and MSVC are known to have used the technique. It was a harmless trick, since at language level this was not an lvalue and its constness was undetectable. That extra const would generally reveal itself only in diagnostic messages issued by the compiler.

然而,随着 C++11 中右值引用的出现,可以在 this 的类型上检测这个额外的 const.例如,以下代码在 C++11 中有效

However, with the advent of rvalue references in C++11 it became possible to detect this extra const on the type of this. For example, the following code is valid in C++11

struct S
{
  void foo() { S *&&r = this; }
};

然而,在仍然使用上述技巧的实现中,它通常无法编译.GCC 从此放弃了该技术.MSVC++ 仍然使用它(从 VS2017 开始),这阻止了上述完全有效的代码在 MSVC++ 中编译.

Yet it will typically fail to compile in implementations that still use the aforementioned trick. GCC has since abandoned the technique. MSVC++ still uses it (as of VS2017), which prevents the above perfectly valid code from compiling in MSVC++.

相关文章