【发布时间】:2016-10-06 17:47:43
【问题描述】:
我有 2 节课:
template<typename T>
class base{
T t;
public:
base(base &&b): t(std::move(b.t)){}
};
template<typename T, typename T2>
class derived : protected base<T>{
T2 t2;
public:
derived(derived &&d): base<T>(std::move(d)), t2(std::move(d.t2)){}
};
我将整个 d 对象移动到 derived move-constructor 中以初始化 base 部分,d 变得无效,但我仍然需要它来使用它的部分进行 t2 初始化
这样的事情有可能吗?
【问题讨论】:
-
我很确定
t2(std::move(t2))要么不会编译,要么是未定义的行为。 -
base(std::move(d))有点像移动切片。base只知道t并且只移动t,但这会让您感到不舒服,因为在移动之后对象需要安全地丢弃,此时只有base满足该要求。 Crom 只知道derived::t2中的内容。但这对于任何派生对象都是正确的。您永远无法移动派生对象,这太疯狂了。只要在derived的移动完成后,derived就可以被处理掉,我想你就可以走了。移动d的base部分,然后移动d的derived部分。 -
std::move实际上并没有移动任何东西,它只是对右值引用的强制转换。移动构造函数是实际修改数据的对象。而且您知道,在您的情况下,base移动构造函数不会使d.t2无效。我相信你的代码是正确的。 -
这很好...
base(std::move(d))可能会导致d的base部分“无效”(无论是什么,它都可能被归零等).. . 但是派生类型的其余部分仍然可以通过d.t2安全访问...base移动构造函数将无法触及它 -
代码应该是正确的,但是,为了清楚起见,我会在第一步添加
static_cast。这意味着实际上仅移动了对象的基础部分。这不会对代码产生任何实际影响。
标签: c++ c++11 constructor initialization move-semantics