6

我有一个菱形的类层次结构,其中没有默认构造函数,也没有复制构造函数。我拥有的两个构造函数是一个“移动”,另一个是对对象的左值引用:

struct base {
    base(base&&) = default;
    base(member_type&& m): member_(std::move(m)) {}
    member_type member_;
};

struct virt_1: virtual base {
    virt_1(virt_1&& rhs): base(std::move(rhs)) {}
    virt_1(member_type&& m): base(std::move(m)) {}
};

struct virt_2: virtual base {
    virt_2(virt_2&& rhs): base(std::move(rhs)) {}
    virt_2(member_type&& m): base(std::move(m)) {}
};

struct concrete: virt_1, virt_2 {
    concrete(concrete&& rhs) // ???
};

除了不使用菱形层次结构外,是否可以为具体类实现移动构造函数?

谢谢!

4

2 回答 2

9

要求编译器提供实现有什么问题?

concrete(concrete&&) = default;

我也会将virt_1and virt_2move 构造函数定义为默认值。

如果你真的想写,你可以写出来:

concrete(concrete&& rhs)
: base(std::move(rhs)), virt_1(std::move(rhs)), virt_2(std::move(rhs))
{ }

或者,如果您真的喜欢打字:

    concrete(concrete&& rhs)
    : base(static_cast<base&&>(rhs)),
      virt_1(static_cast<virt_1&&>(rhs)),
      virt_2(static_cast<virt_2&&>(rhs))
    { }

virt_1和基础的初始化器virt_2是无用的,因为它们只调用base构造函数,并且因为它是一个虚拟基础,所以在调用它时它们不会这样做concrete,但是由于您选择的构造函数,您不能默认构造它们并且是必需的用右值初始化它们,即使它们什么都不做。

于 2013-07-08T11:50:48.397 回答
1

当然。任何virtual在层次结构中具有基数的构造函数都负责初始化该基数。本质virtual上,层次结构中基层之下的任何类都继承了初始化基层的权限。

在这种情况下,默认的移动构造函数应该做正确的事情。我建议还指定concrete : private virtual base以澄清正在发生的事情。

是一个工作演示。

于 2013-07-08T11:39:17.523 回答