那么"this"的类型是什么?为什么"this"不是左值?

so what is the type of "this" ? Why is "this" not a lvalue?

本文关键字:this 是什么 类型 那么 为什么      更新时间:2023-10-16

假设对象是

class A {
public :  void Silly(){
    this = 0x12341234;
}

我知道我会得到编译错误' "this"不是左值。"但这也不是暂时的。那么"this"的假设声明是什么呢?

编译器:mac上的GCC 4.2编译器。

对于某些类X, this具有X* this;类型,但不允许对其进行赋值,因此即使它实际上没有X *const this类型,它的行为几乎就像阻止赋值一样。正式地说,它是一个prvalue,它与整数字面值是同一类别,所以尝试给它赋值大致相当于尝试给'a'10赋一个不同的值。

请注意,在早期的 c++中,this是一个左值——允许赋值给this——这样做是为了处理对象的内存分配,有点类似于为类重载newdelete(当时还不支持)。

不可能为this提供"声明"。在c++中没有办法"声明"一个右值。并且this是右值,正如您已经知道的。

左值和反值是表达式产生这些值的属性,而不是声明或对象的属性。在这种情况下,甚至可以认为不可能声明左值。你声明了一个对象。左值是使用该对象的名称作为表达式时产生的值。在这种意义上,"声明右值"answers"声明左值"都是矛盾修饰法表达式。

你的问题似乎也表明"作为左值"answers"作为临时值"的属性在某种程度上是互补的,即所有东西都被认为是左值或临时值。实际上,"暂时"的属性与这里没有关系。所有表达式要么是左值,要么是右值。而this恰好是右值

另一方面,可以将

临时值视为左值或右值,这取决于您如何访问临时值。

注:注意,顺便说一句,在c++中(与C相反)普通函数是左值。

首先,this不是一个变量——它是一个关键字。当用作右值时,其类型为A *A const *。在现代c++中,禁止对this赋值。你也不能取this的地址。换句话说,它不是一个有效的左值。

回答第二部分,"为什么this不是左值",我猜测委员会的实际动机,但优势包括:

  1. 赋值给this在逻辑上没有多大意义,所以它没有必要出现在赋值的左侧。将其设置为右值强调禁止这样做没有多大意义,并且意味着标准不必定义如果这样做会发生什么。
  2. 使其为右值可以防止您获取指向它的指针,这反过来又减轻了为它提供地址的任何需要的实现,就像register修改的自动变量一样。例如,它可以在非静态成员函数中分配一个寄存器来存储this。如果你使用一个const引用,那么除非使用允许巧妙的优化,否则它需要被复制到有地址的地方,但至少如果你连续做两次,它不必是相同的地址,因为如果this是一个声明的变量,它需要。

你会得到一个编译错误,因为this是一个const指针,指向与该类类型相同的类的实例。虽然可以使用它来更改非const限定方法、调用方法和操作符中的其他类成员,但不能对其进行赋值。还要注意,因为它是一个实例,所以静态方法没有this指针。

假设:

class Whatever
{
    // your error because this is Whatever* const this;
    void DoWhatever(const Whatever& obj) { this = &obj; } 
    // this is ok
    void DoWhatever(const Whatever& obj) { *this = obj; }
    // error because this is now: const Whatever* const this;
    void DoWhatever(const Whatever& obj) const { *this = obj; } 
    // error because this doesn't exist in this scope
    static void DoWhatever(const Whatever& obj) { *this = obj; }
};