提问人:Luchian Grigore 提问时间:3/26/2012 最后编辑:BenLuchian Grigore 更新时间:7/24/2012 访问量:564
“X x = x = X();”合法的 C++ 吗?
Is `X x = x = X();` legal C++?
问:
我减少了这个:
struct A
{
int * x;
A() : x( x = new int() )
{
}
};
到以下内容:
int m = m = 3;
//or
struct X;
//...
X x = x = X();
对我来说似乎是合法的。我不明白你为什么要这样做,但它合法吗?在某些情况下,您是否想这样做(不是这样,我意识到这完全没用)?int
答:
这在语法上是合法的,但在运行时会导致未定义的行为。在这样的声明中:
X x = x = X();
第二个是赋值,它赋值给一个未初始化的变量。(第一种是简单的语法,表示后面的内容应该用于复制初始化;它不是赋值。=
=
这取决于你如何定义“合法”。它将编译;这并不意味着它保证有效。
在执行完整语句之前,未初始化。它还不是 X
。因此,执行意味着创建一个临时变量并调用未初始化的变量。X x = ...
x
x = X()
X
X::operator=(const X&)
x
在尚未初始化的非 POD 类实例上调用函数(尚未调用其构造函数)会产生未定义的行为。如果是 POD 类型(或在 C++11 中是微不足道的),那么它将起作用。但除此之外没有。X
评论
int m = m = 3;
//or
struct X;
//...
X x = x = X();
这是合法的(如果你定义了一个名为 X 的结构,但你的结构名为 A,你也不需要用 c++ 编写结构),但两者都是未定义的行为。
x(x = new int())
是合法的,但也有未定义的行为。
评论
这是合法的语法。X 在其自身定义的范围内。您可能希望对象引用自身的情况是循环链表,其行如下:
struct Node {
Node( Node *pNext_ ) : pNext( pNext_ ) {
}
// ...
Node *pNext;
};
Node empty( &empty };
这个空列表由一个虚拟节点组成,该虚拟节点具有指向自身的链接。这既明确又有用。请注意,我们取 empty 的地址,即使 Node 是非 POD 并且尚未构建,这也是合法的。我不认为像你的例子那样允许赋值是直接有用的,但语言很难允许我的,也不允许你的赋值。int m = m = 3;
若要了解这如何延续到成员构造函数,请考虑:
struct A {
Node list;
A() : list( &list ) {}
}
一旦名称在范围内,也可以允许与它进行分配。
评论
"Are there cases where you'd want to do this (not the int case, I realize that's completely useless)?"
Node empty( &empty };
empty
pNext( pNext_ )
评论
y = A()
operator=
x( x = new int() )
x(new int())
int x = x++;