'this'指针的类型

Type of 'this' pointer

本文关键字:类型 this 指针      更新时间:2023-10-16

正如标题中提到的,我想知道'this'指针的类型。

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

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

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

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

以下是语言规范的相关引文(强调我的)

9.3.2 这个指针

在非静态 (9.3) 成员函数的主体中,关键字为 一个 prvalue 表达式,其值是 的 对象地址 调用该函数。成员函数中的此类型为 类 X 是 X*。如果成员函数声明为 const,则类型 这是常量 X*,如果成员函数被声明为易失性,则 此类型是易失性 X*,如果声明了成员函数 常量易失性,其类型是常量易失性 X*。[ 注:因此在 常量成员函数,为其调用函数的对象 通过常量访问路径进行访问。—尾注 ]


在 C++98/C++03 时代,几个编译器使用了内部实现技巧,这是毫无价值的:他们将this指针解释为常量指针,例如 ClassName *constClassName的非恒定方法中。这显然有助于他们确保this的非可修改性。众所周知,GCC和MSVC已经使用了该技术。这是一个无害的伎俩,因为在语言层面上,this不是一个左值,它的恒定性是无法察觉的。该额外const通常仅在编译器发出的诊断消息中显示。

但是,随着 C++11 中右值引用的出现,可以检测到this类型的这种额外const。例如,以下代码在 C++11 中有效

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

然而,它通常无法在仍然使用上述技巧的实现中进行编译。此后,海湾合作委员会放弃了这项技术。MSVC++仍然使用它(截至VS2017),这阻止了上述完全有效的代码在MSVC++中编译。

const 表示您无法更改指针指向的内容。

ClassName *const

const ClassName *

后者是指向对象的指针,并且无法修改对象(无论如何,使用指针)。 前者是一个指针,不能重新指向另一个对象(也不是 NULL),至少不用诉诸讨厌的强制转换。

当然还有组合:

const ClassName *const

这将是一个指针,不能更改为指向其他内容,也不能用于更改它指向的对象。

至于为什么你的编译器this指针显示为常量,不鼓励你this指向它开头的对象以外的对象确实是有道理的。

上面有很多

讨论,主要帖子没有给出正确的答案。人们可能不会挖掘评论,因此最好作为主端口(PS)共享。

我对 Ubuntu 和 VC++ 进行了一些调查,但没有正确的输出(使用 typeid(X).name )。


对于类类型 X 的成员函数,此指针的类型为 X* 常量。如果使用 const 限定符声明成员函数,则类 X 的成员函数的 this 指针的类型为 const X* const。MSDN 链接


从概念上讲,这也是正确的,因为普通成员函数是"X* const",这就是为什么它不是 l 值(因为您无法更改其内容)。

摘自

C++ Primer 4th ed:"在普通的nonconst成员函数中,this的类型是class类型的const pointer。我们可以更改this指向的值,但不能更改this持有的地址。在 const 成员函数中,this 的类型是 const class 类型对象的const pointer。我们既不能改变this指向的对象,也不能改变this所持有的地址。这意味着无论VC++智能感知显示什么都是正确的。