“这个”的类型指针

发布于 2024-11-08 22:01:34 字数 194 浏览 2 评论 0原文

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

○愚か者の日 2024-11-15 22:01:35

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

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


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


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

There were a lot of discussions above and main post didn't present correct answer.
People might not dig comments so its better to share as main port (PS).

I did some investigation on Ubuntu as well as on VC++ but there is no correct output (using typeid(X).name ).


The type of this pointer for a member function of a class type X, is X* const. If the member function is declared with the const qualifier, the type of the this pointer for that member function for class X, is const X* const.
MSDN link


Conceptually this is correct also, for normal member function is "X* const" that's why it isn't l-value (as you can't change its contents).

最佳男配角 2024-11-15 22:01:35

C++ Primer 第 4 版摘录:“在普通的 nonconst 成员函数中,this 的类型是指向 const 指针 class 类型。我们可以更改 this 指向的值,但不能更改 this 成员中的地址。函数,this 的类型是指向 const class 类型对象的 const 指针 我们既不能更改 this 指向的对象,也不能更改 this 的地址。成立。”这意味着 VC++ 智能感知显示的任何内容都是正确的。

An excerpt from C++ Primer 4th ed: "In an ordinary nonconst member function, the type of this is a const pointer to the class type. We may change the value to which this points but cannot change the address that this holds. In a const member function, the type of this is a const pointer to a const class - type object. We may change neither the object to which this points nor the address that this holds." This means whatever VC++ intellisense was displaying is correct.

避讳 2024-11-15 22:01:34

此指针的类型为 ClassName *const ClassName *,具体取决于是否在类 ClassName< 的非常量方法或 const 方法中检查它/代码>。指针 this 不是左值。

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

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

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

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

9.3.2 this 指针

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


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

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

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

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

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
  }
};

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 The this pointer

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 ]


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.

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; }
};

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++.

〆凄凉。 2024-11-15 22:01:34

const 意味着你不能改变指针指向的内容。

ClassName *const

与后者有很大不同,

const ClassName *

后者是指向对象的指针,并且该对象无法修改(无论如何使用指针)。前者是一个指针,不能重新指向另一个对象(也不能为 NULL),至少在不使用讨厌的转换的情况下是这样。

当然还有一种组合:

const ClassName *const

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

至于为什么编译器将 this 指针显示为 const,不鼓励您将 this 指向除它开头的对象之外的对象,这确实是有道理的。

The const means you cannot change what the pointer points to.

ClassName *const

is much different from

const ClassName *

The latter is a pointer to an object and the object cannot be modified (using the pointer, anyway). The former is a pointer which cannot be re-pointed to another object (nor NULL), at least without resorting to nasty casting.

There is of course also the combination:

const ClassName *const

This would be a pointer which cannot be changed to point to something else, nor can it be used to change the object it points to.

As for why your compiler shows this pointers as being const, it does make sense that you are discouraged from making this point to an object other than the one it began with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文