正如标题所述,我想了解'this'
指针的类型。
我正在开发一个项目,观察到在Windows使用VC++ 2008时'this'
指针的类型为"ClassName * const this"
。我想知道把this指针变成常量指针的必要性和原因。谢谢。
正如标题所述,我想了解'this'
指针的类型。
我正在开发一个项目,观察到在Windows使用VC++ 2008时'this'
指针的类型为"ClassName * const this"
。我想知道把this指针变成常量指针的必要性和原因。谢谢。
这个指针的类型要么是ClassName *
,要么是const ClassName *
,具体取决于它是否在类ClassName
的非const或const方法内被检查。指针this
不是lvalue。
class ClassName {
void foo() {
// here `this` has `ClassName *` type
}
void bar() const {
// here `this` has `const ClassName *` type
}
};
你上面提到的观察结果是具有误导性的。指针this
不是一个L值,这意味着它不可能有ClassName * const
类型,也就是说,它不能在*
右边有一个const
。指针类型的非L值不能是常量或非常量。在C ++语言中根本没有这样的概念。你观察到的必须是特定编译器的内部问题。从形式上讲,这是不正确的。 this
指针解释为常量指针,例如类 ClassName
的非常量方法中的 ClassName * const
。这显然有助于确保this
的不可修改性。已知GCC和MSVC使用了该技术。这是一种无害的技巧,因为在语言层面上,this
不是L值,其常量性是不可检测的。那个额外的const
通常只会在编译器发出的诊断消息中显示出来。this
上的额外const
。例如,以下代码在C ++ 11中是有效的:struct S
{
void foo() { S *&&r = this; }
};
然而,在仍然使用上述技巧的实现中,它通常无法编译。 GCC已经放弃了这种技术。 MSVC ++仍在使用它(截至VS2017),这会阻止上面的完全有效的代码在MSVC ++中编译。
const表示你不能更改指针所指向的内容。
ClassName *const
与之大不相同
const ClassName *
后一种是指向对象的指针,而且对象不可修改(至少使用该指针无法修改)。前一种是指针,无法重新指向另一个对象(也不能为NULL),除非采用丑陋的转换。
当然也有两者的结合:
const ClassName *const
this
指针显示为 const,这样做确实有道理,因为您不应该让 this
指向除了初始对象之外的其他对象。this = ...
或 This& p = *this
(假设 p
不是 const
)。 - Tony Delroy5
也不能被改变或分配。你不能执行 5 = 3
。然而,5
的类型是 int
。它是 int
而不是 const int
。说 5
的类型是 const int
是不正确的。同样适用于 this
指针。它不是一个左值(就像 5
不是一个左值一样)。不是左值的东西不能是 const 或非 const。因此,this
指针不能是 const
,上面的分析从正式的角度来看是完全错误的。 - AnT stands with RussiaClassName const *
而不是 const ClassName *
。同样,对于 ClassName const * const
,我也更倾向于使用 const ClassName * const
。从右到左阅读,很容易看出 const 应用的位置。 - Thomas Eding上面有很多讨论,但主贴没有给出正确的答案。人们可能不会深入评论区,因此最好将其分享为主要文章(PS)。
我对Ubuntu和VC++进行了一些调查,但都没有正确输出(使用typeid(X).name
)。
类类型X的成员函数的this指针类型是X* const。如果成员函数被声明为const限定符,则该成员函数所属的类X的this指针类型是const X* const。MSDN链接
从概念上讲也是正确的,对于常规成员函数来说,“X* const”就是它不是左值的原因(因为你不能更改它的内容)。
this
指针是一个rvalue(请参见语言标准中的9.3.2 / 1)。非类rvalue不能具有const限定类型(请参见语言标准中的3.10 / 9)。无论哪本书声称什么都不相关,无论是由谁编写的。如果一些书与语言规范相矛盾,则该书是错误的。 - AnT stands with Russia
this
(或任何其他表达式)的类型不是由调用堆栈确定的。 - MSaltersthis
本身,而不是它所指向的内容。 - AnT stands with Russiathis
是一个"const指针"总是不正确的。再次强调,this
是标量类型的右值。标量类型的右值无法是const或non-const。第四版于2001年出版,这意味着它相当古老。检查更晚的版本可能是有意义的。错误可能已经被修复了。 - AnT stands with Russia