正如标题中所提到的,我想知道'this'
指针的类型。
我正在开发一个项目,我在使用VC ++ 2008的Windows上观察到'this'
指针的类型为"ClassName * const this"
。我想知道是什么需要/要求这个指针是一个常量指针。感谢。
答案 0 :(得分:47)
此指针的类型是ClassName *
或const ClassName *
,具体取决于它是否在类ClassName
的非const或const方法中进行检查。指针this
不是左值。
class ClassName {
void foo() {
// here `this` has `ClassName *` type
}
void bar() const {
// here `this` has `const ClassName *` type
}
};
您上面提到的观察结果具有误导性。指针this
不是左值,这意味着它不可能具有ClassName * const
类型,即它不可能在{{的右侧有const
1}}。指针类型的非左值不能是const或非const。在C ++语言中根本没有这样的概念。你观察到的必须是特定编译器的内部怪癖。形式上,这是不正确的。
以下是语言规范(强调我的)的相关引用
9.3.2此指针
在非静态(9.3)成员函数的主体中,关键字是 一个prvalue表达式,其值是对象的地址 调用该函数。 在成员函数中的类型 X类是X *。如果成员函数声明为const,则为 这是const X *,如果成员函数声明为volatile,则 这个类型是volatile X *,如果声明了成员函数 const volatile,这个类型是const volatile X *。 [注意:因此在 const成员函数,调用该函数的对象 通过const访问路径访问。 - 后注]
在C ++ 98 / C ++ 03中,有几个编译器使用内部实现技巧,这是值得的:他们将*
指针解释为常量指针,例如: this
在类ClassName *const
的非常量方法中。这显然有助于他们确保ClassName
的不可修改性。已知GCC和MSVC已经使用该技术。这是一个无害的伎俩,因为在语言层面this
不是左值,而且它的常数是不可检测的。额外的this
通常只会在编译器发出的诊断消息中显示出来。
然而,随着C ++ 11中rvalue引用的出现,有可能在const
的类型上检测到这个额外的const
。例如,以下代码在C ++ 11中有效
this
然而,它仍然无法在仍然使用上述技巧的实现中进行编译。 GCC此后放弃了该技术。 MSVC ++仍然使用它(自VS2017起),这阻止了上述完全有效的代码在MSVC ++中编译。
答案 1 :(得分:3)
const表示你无法改变指针指向的内容。
ClassName *const
与
有很大不同const ClassName *
后者是指向对象的指针,无法修改对象(无论如何都使用指针)。前者是一个指针,不能重新指向另一个对象(也不是NULL),至少不要求助于讨厌的转换。
当然也有组合:
const ClassName *const
这将是一个无法更改为指向其他内容的指针,也不能用于更改它指向的对象。
至于为什么你的编译器将this
指针显示为const,有意义的是你不要让this
指向除了它之外的对象。
答案 2 :(得分:1)
上面有很多讨论,主要帖子没有提供正确答案。 人们可能不会挖掘评论,因此最好分享为主要端口(PS)。
我对Ubuntu以及VC ++进行了一些调查,但没有正确的输出(使用typeid(X).name
)。
类类型X的成员函数的this指针类型是X * const。如果使用const限定符声明成员函数,则类X的该成员函数的this指针的类型是const X * const。 MSDN link
从概念上讲这也是正确的,因为普通成员函数是“X * const”,这就是为什么它不是l值(因为你不能改变它的内容)。
答案 3 :(得分:-3)
摘自C ++ Primer 4th ed:“在普通的nonconst
成员函数中,this
的类型是const pointer
类型的class
。我们可能会更改this
指向但不能更改this
所占地址的值。在const
成员函数中,this
的类型为const pointer
const class
- 类型对象。我们可能既不会更改this
指向的对象,也不会更改this
所持有的地址。“这意味着VC ++ intellisense显示的是正确的。