那么“这个”的类型是什么?为什么“这个”不是左值?

时间:2011-09-07 23:29:19

标签: c++

说对象是

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

我知道我会得到编译错误'“这个”不是左值。“但那也不是暂时的。那么“这个”的假设宣言是什么?

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

5 个答案:

答案 0 :(得分:6)

对于某些类X,this的类型为X* this;,但您不能分配给它,因此即使它实际上没有类型X *const this,它的行为几乎就像防止任务一样。正式地说,它是prvalue,与整数文字类似,所以尝试分配它大致等同于尝试为'a'10分配不同的值

请注意,在早期 C ++中,this是左值 - 允许分配给this - 您这样做是为了处理对象的内存分配,模糊地类似于为类重载newdelete(当时尚不支持)。

答案 1 :(得分:4)

无法为this提供“声明”。没有办法在C ++中“声明”一个rvalue。正如您所知,this是一个右值。

Lvalueness和rvalueness是产生这些值的表达式的属性,而不是声明或对象的属性。在这方面,人们甚至可以争辩说也不可能宣布左值。你声明一个对象。左值是将该对象的名称用作表达式时生成的值。从这个意义上说,“宣布一个右翼”和“宣布一个左值”都是矛盾的表达。

你的问题似乎也暗示“作为左倾”和“作为临时”的属性在某种程度上是互补的,即一切都被认为是左值或临时值。实际上,“作为一个临时”的财产在这里没有生意。所有表达式都是左值或右值。 this恰好是一个右值。

另一方面,Temporaries可以被视为rvalues或lvalues,具体取决于你如何访问临时值。

P.S。注意,BTW,在C ++中(与C相反)普通函数是左值。

答案 2 :(得分:3)

首先,this不是变量 - 它是关键字。用作右值时,其类型为A *A const *。在现代C ++中,禁止分配给this。您也不能使用this的地址。换句话说,它不是一个有效的左值。

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

您收到编译器错误,因为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; }
};