使用VS2008编译的C/C++中存在结构复制问题



我使用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具有不同的类型,则两个调用略有不同,后者先进行转换,然后进行复制。尽管副本通常被删除,但它仍然需要一个副本构造函数。

最新更新