C++ 那么,什么是“的类型?”;这是什么?为什么是;这";不是左撇子?
假设对象是C++ 那么,什么是“的类型?”;这是什么?为什么是;这";不是左撇子?,c++,C++,假设对象是 class A { public : void Silly(){ this = 0x12341234; } 我知道我会得到编译器错误“this”不是左值。但它也不是临时的。那么,“这个”的假设性声明是什么 编译器:mac上的GCC4.2编译器。对于某些X类,this的类型为X*this,但不允许分配给它,因此即使它实际上没有类型X*const this,它的行为几乎就像阻止分配一样。正式地说,它是一个prvalue,与整数文本一样属于同一类别,因此尝试将其赋值大致相当于尝
class A {
public : void Silly(){
this = 0x12341234;
}
我知道我会得到编译器错误“this”不是左值。但它也不是临时的。那么,“这个”的假设性声明是什么
编译器:mac上的GCC4.2编译器。对于某些X类,
this
的类型为X*this代码>,但不允许分配给它,因此即使它实际上没有类型X*const this
,它的行为几乎就像阻止分配一样。正式地说,它是一个prvalue
,与整数文本一样属于同一类别,因此尝试将其赋值大致相当于尝试将不同的值赋值给'a'
或10
<>注意,在早期C++中,<代码> < <代码>是一个LVald——赋值给<代码>这个< /C> > -您这样做是为了处理对象的内存分配,模糊地类似于重载<代码>新< /C> >和<代码>删除<代码>,用于类(当时还不支持)。此
不是一个变量-它是一个关键字。当用作右值时,其类型为a*
或a const*
。在现代C++中,禁止使用< <代码> > <代码>。您也不能获取此
的地址。换句话说,它不是一个有效的左值。您会得到一个编译器错误,因为这是一个常量指针,指向与该类类型相同的类的实例。虽然可以使用它来更改非常量限定方法、调用方法和运算符中的其他类成员,但不能对其赋值。还要注意,因为它是一个静态方法没有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; }
};
无法为此
提供“声明”。在C++中没有办法“声明”一个rof值。这是一个右值,你已经知道了
左值和右值是产生这些值的表达式的属性,而不是声明或对象的属性。在这方面,人们甚至可以说,宣布左值也是不可能的。您声明了一个对象。左值是将该对象的名称用作表达式时产生的值。从这个意义上说,“声明右值”和“声明左值”都是矛盾修饰法
你的问题似乎还表明,“作为左值”和“作为临时性”的属性在某种程度上是互补的,即所有东西都应该是左值或临时性的。事实上,“暂时性”的财产在这里没有任何意义。所有表达式都是左值或右值。而这个
正好是一个右值
另一方面,临时值可以被视为右值或左值,这取决于您访问临时值的方式
S.Note,BTW,在C++中(与C相反),普通函数是LValue.< /P> < P>,回答第二部分,“为什么是代码>这个< /代码>不是LValk”,我推测委员会的实际动机,但优点包括:
分配给此
没有太多逻辑意义,因此没有特别需要将其显示在分配的左侧。将其设为右值强调禁止它没有多大意义,这意味着标准不必定义如果你这样做会发生什么
将其设为右值可以防止您将指针指向它,这反过来又免除了为其提供地址的任何需要,就像寄存器
修改的自动变量一样。例如,它可以在非静态成员函数中使用一个寄存器来存储此
。如果使用const引用,则除非使用允许巧妙的优化,否则需要将其复制到具有地址的某个位置,但如果快速连续执行两次,则至少不需要相同的地址,因为如果this
是声明的变量,则需要相同的地址
出于兴趣,必须
try{this=madness;}catch(…){this=sparta;}
哪个编译器会给你这个消息?@Oli:如果代码更改为this=(A*)0x12341234代码>,VC++报告“左操作数必须是l值”——有点类似。litb在别处给出了一个很好的例子。假设实例指针被称为\u this
,我们已经定义了\n this(\u this+0)
@Gman:我不明白你能给我一个参考或链接吗?“当用作右值时,它的类型是a*
或a*const
”你的意思是a*
或a const*
@Seva:有一个简单的规则可以帮助你保持清晰。如果你看一个声明,比如T*p
,T
是目标类型,p
是指针本身的名称,*
是介于两者之间的“墙”。如果将const
(或volatile
)放在墙的指针一侧,则会影响指针。如果你把它放在墙的“类型”一边,它会影响指针指向的类型。好吧,从C背景来看,我倾向于把右值的声明看作“const-levalue-type”@Ajeet:这真的很奇怪。在这方面,C语言与C++没有太大的不同。在C语言中,const int
声明声明一个左值,而不是右值。虽然不能声明右值,但可以(例如)声明/定义一个类型的左值,该类型的值可以不经过转换就分配给该左值。@AndreyT:Agree。只是我的心理感知把“右值”和“真值”区分开来,前者是常量“左值”,而后者是真正没有地址的临时值。rvalue(const'lvalue')确实有一个地址。只是编译器在它们周围建立了防火墙。@AndreyT:如果函数是左值函数,那么函数赋值就不可能了吗?void f(){}void f1(){}main(){f=f1;}顺便说一句,这会给出一个有趣的错误“can”