我有以下使用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???
为什么我会得到如此奇怪的结果?
答案 0 :(得分:3)
你刚做了一些非常讨厌的事情:你放弃了你的const限定符。
const TEST_STRUCT v2 = v1;
或
const TEST_STRUCT v2(v1);
会给你你想要的东西......除非你决定违反const限定词,这非常非常糟糕。
答案 1 :(得分:1)
正如所指出的,您尝试分配的对象是临时对象,而原始对象保持不变。这是编译器没有抱怨的原因之一。如果你想要转换实际对象,你可以使用这样的东西:
const_cast<TEST_STRUCT&>(v2) = v1;
这仍然无法正常工作,因为当应用于以const
对象开始其生命周期的对象时,此转换会导致未定义的行为:对象可能存在于只读内存中,或者编译器可能存在用相应的初始值替换对其成员的访问。
设置const
对象成员的唯一方法是在构建期间。你struct
方便地有两个构造函数:你声明的默认构造函数和编译器将为你创建的复制构造函数,除非它被声明或者一个子对象(非静态成员或基类)没有复制构造函数。因此,你只需写:
TEST_STRUCT const v2(v1);
或
TEST_STRUCT const v2 = v1;
在这种情况下,两个调用在语义上是等效的,尽管后一个调用理论上涉及两个副本。如果v1
具有不同的类型,则两个调用稍有不同,后者调用首先转换然后复制。虽然副本通常被省略,但它仍然需要复制构造函数。