我使用Visual Studio 2008编译了以下C/C++代码:
struct TEST_STRUCT{
int nV;
float v;
TEST_STRUCT()
{
nV = 0;
v = 0.0;
}
};
TEST_STRUCT v1;
v1.nV = 100;
v1.v = 2.0;
const TEST_STRUCT v2; //Making it 'const' to prevent any further changes
(TEST_STRUCT)v2 = v1;
int a = v2.nV; //'a' is 0, why???
为什么我得到这样一个奇怪的结果?
您刚刚做了一件非常糟糕的事情:丢弃了const限定符。
const TEST_STRUCT v2 = v1;
或
const TEST_STRUCT v2(v1);
会给你想要的。。。除非您决定违反const限定符,否则这非常非常糟糕。
如前所述,您试图分配给的对象是一个临时对象,而原始对象保持不变。这也是编译器没有抱怨的原因之一。如果你想投射实际的物体,你可以使用这样的东西:
const_cast<TEST_STRUCT&>(v2) = v1;
这仍然不一定有效,因为当将此强制转换应用于以const
对象开始其生命周期的对象时,会导致未定义的行为:该对象可能存在于只读内存中,或者编译器可能会用其相应的初始值替换对其成员的访问。
设置const
对象成员的唯一方法是在构造期间。struct
方便地有两个构造函数:您声明的默认构造函数和编译器将为您创建的复制构造函数,除非声明了它,或者其中一个子对象(非静态成员或基类)没有复制构造函数。因此,你只需要写:
TEST_STRUCT const v2(v1);
或
TEST_STRUCT const v2 = v1;
在这种情况下,两个调用在语义上是等价的,尽管后一个调用理论上涉及两个副本。如果v1
具有不同的类型,则两个调用略有不同,后者先进行转换,然后进行复制。尽管副本通常被删除,但它仍然需要一个副本构造函数。