2015-11-20 21 views
2

对未初始化的数据使用赋值是否危险?使用赋值是危险的,因为以前的值无效

使用赋值运算符时,何时应该格外小心?

我问的原因是因为我在看视频C++ and Beyond 2012: Andrei Alexandrescu - Systematic Error Handling in C++,他在那里显示Expected<T>类,它有一个值或一个例外。此举构造函数定义

Expected(Expected&& rhs) : .. { 
    if (gotHam) new(&ham) T(std::move(rhs.ham)); 
    ... 

其中ham被定义为

union { 
    T ham; 
    std::exception_ptr spam; 
}; 

他解释背后使用新的布局和resoning在28:49,他说,因为他是用一个结合中,他有要格外小心地管理初始化。他在29:14则进一步指出:

因为分配假设 前值是有效

我不明白这一点,我不能使用赋值 - 为什么会转让要求以前的值是有效的?我想这一点,比较的东西:

int i; // unassigned, i.e. not valid 
i = 0; // so this would thus be dangerous? 

我想,也许它已与工会做,而且是未初始化的,但我仍然没有看到转让的危害。为什么一项任务会关注以前的价值?

+0

认为T是一个管理内存的类,但构造函数从未执行过。 –

+0

@RichardHodges好点 - 我的理解是,operator =会创建这些数据,类似于构造函数的操作。但我想运算符=可能会假设这些构造是由前面的构造函数创建的,因此跳过这一步。我在正确的轨道上吗? :) – Default

+1

联盟不承担任何责任。这只是记忆。如何初始化和使用该内存取决于您。这就是为什么Andrei的例子有一个标志 - 告诉周围代码哪个成员是有效的。 –

回答

2

他的意思是T的构造函数从来没有跑过。因此你不能以任何方式使用火腿物体。把它作为一个这样的联合是我知道正式拥有一个可用的命名对象,而不需要构造器正在运行的唯一途径。

这就是为什么我不相信工会在C++程序中有任何地位。

+0

我不明白的是操作符=如何“使用”对象。不是操作符=与构造函数类似,即它将数据分配给对象? – Default

+3

编号Operator =是一个赋值运算符,它使用已经构建的对象。 – SergeyA

+1

@默认情况下,类似于构造函数的运算符是复制构造函数,而不是赋值运算符。 –