0

我有以下使用 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???

为什么我会得到如此奇怪的结果?

4

2 回答 2

3

你只是做了一些非常讨厌的事情:你丢弃了你的 const 限定符。

const TEST_STRUCT v2 = v1;

或者

const TEST_STRUCT v2(v1);

会给你你想要的......除非你决心违反非常非常糟糕的 const 限定符。

于 2012-09-15T22:50:51.747 回答
1

正如所指出的,您尝试分配的对象是临时对象,而原始对象保持不变。这是编译器没有抱怨的原因之一。如果你想投射实际的对象,你会使用这样的东西:

const_cast<TEST_STRUCT&>(v2) = v1;

这仍然无法正常工作,因为这种强制转换在应用于开始其作为对象的生命周期的对象时会导致未定义的行为const:对象可能存在于只读内存中,或者编译器可能会通过其相应的成员替换对其成员的访问初始值。

设置对象成员的唯一方法const是在构造期间。您可以struct方便地使用两个构造函数:您声明的默认构造函数和编译器将为您创建的复制构造函数,除非它被声明或子对象之一(非静态成员或基类)没有复制构造函数。因此,您只需编写:

TEST_STRUCT const v2(v1);

或者

TEST_STRUCT const v2 = v1;

在这种情况下,两个调用在语义上是等效的,尽管后者调用理论上涉及两个副本。如果v1类型不同,则两个调用略有不同,后者调用首先转换然后复制。尽管副本通常被省略,但它仍然需要一个副本构造函数。

于 2012-09-15T23:28:17.223 回答