C++ “this”指针的类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6067244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type of 'this' pointer
提问by Purnima
As mentioned in the title, I would like to know about the type of 'this'
pointer.
正如标题中提到的,我想知道'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.
我正在处理一个项目,我观察到'this'
指针的类型"ClassName * const this"
在使用 VC++ 2008 的 Windows 上。好吧,我想知道使 this 指针成为常量指针的需要/要求是什么。谢谢。
回答by AnT
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.
此指针的类型是ClassName *
或const ClassName *
,具体取决于它是在类的非常量方法还是常量方法中进行检查ClassName
。指针this
不是左值。
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.
你上面提到的观察是误导性的。指针this
是不是左值,这意味着它不可能有ClassName * const
类型的,即它不能可能具有const
到的右侧*
。指针类型的非左值不能是 const 或非常量。C++ 语言中根本没有这样的概念。您观察到的必须是特定编译器的内部怪癖。从形式上讲,这是不正确的。
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 ]
9.3.2 this指针
在非静态 (9.3) 成员函数的主体中,关键字 this 是一个纯右值表达式,其值是调用该函数的对象的地址。类 X 的成员函数中 this 的类型是 X*。如果成员函数声明为const,则this的类型为const X*,如果成员函数声明为volatile,则this的类型为volatile X*,如果成员函数声明为const volatile,则this的类型为const挥发性 X*。[ 注意:因此在 const 成员函数中,调用该函数的对象是通过 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++98/C++03 时代,一些编译器使用内部实现技巧是毫无价值的:它们将它们的this
指针解释为常量指针,例如ClassName *const
在 class 的非常量方法中ClassName
。这显然有助于他们确保this
. 众所周知,GCC 和 MSVC 已经使用了该技术。这是一个无害的技巧,因为在语言层面this
上不是左值,而且它的常量是不可检测的。这个额外的东西const
通常只会在编译器发出的诊断消息中显示出来。
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
但是,随着 C++11 中右值引用的出现,可以const
在this
. 例如,以下代码在 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++.
然而,在仍然使用上述技巧的实现中,它通常无法编译。GCC 从此放弃了该技术。MSVC++ 仍然使用它(从 VS2017 开始),这阻止了上述完全有效的代码在 MSVC++ 中编译。
回答by John Zwinck
The const means you cannot change what the pointer points to.
const 意味着您不能更改指针指向的内容。
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.
后者是一个指向对象的指针,并且该对象不能被修改(无论如何使用指针)。前者是一个不能被重新指向另一个对象(也不是 NULL)的指针,至少在不诉诸讨厌的转换的情况下是这样。
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.
至于为什么你的编译器将this
指针显示为常量,不鼓励你this
指向一个对象而不是它开始的对象是有道理的。
回答by nky
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).
上面有很多讨论,主要帖子没有给出正确的答案。人们可能不会挖掘评论,所以最好作为主端口 (PS) 共享。
I did some investigation on Ubuntu as well as on VC++ but there is no correct output (using typeid(X).name
).
我对 Ubuntu 和 VC++ 进行了一些调查,但没有正确的输出(使用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
类类型 X 的成员函数的 this 指针的类型是 X* const。如果成员函数是用 const 限定符声明的,则类 X 的该成员函数的 this 指针的类型是 const X* const。 MSDN链接
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).
从概念上讲,这也是正确的,因为普通成员函数是“X* const”,这就是为什么它不是左值(因为您无法更改其内容)。
回答by Purnima
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.
从C ++引物第4版的摘录:“在一个普通的nonconst
成员函数的类型,this
是一个const pointer
给class
类型,我们可以改变到的值。this
点,但不能改变该地址this
保持在。const
成员函数的类型,this
是一个const pointer
到一个const class
- 类型的对象。我们不能改变this
指向的对象和this
保存的地址。” 这意味着 VC++ 智能感知显示的任何内容都是正确的。