【发布时间】:2013-07-05 17:06:59
【问题描述】:
我有一个菱形的类层次结构,其中没有默认构造函数,也没有复制构造函数。我有两个构造函数,一个是“移动”,另一个是对对象进行左值引用:
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) // ???
};
除了不使用菱形层次结构外,是否可以为具体类实现移动构造函数?
谢谢!
【问题讨论】:
-
对我来说听起来很容易出错。虚基的构造函数是从最派生类调用的,应该没有理由不能调用移动构造函数。但是任何进一步的推导,很有可能有人会忘记它,或者做错了。作为一般规则,虚拟基类不应包含数据,或至少具有除默认构造函数之外的任何构造函数,以避免此类问题。
-
@JamesKanze 我很清楚
base不应该包含数据,或者至少有一个默认的构造函数,但在我的上下文中不能这样。但是,如果有人在进一步推导时忘记调用虚拟基构造函数,编译器是否有可能会抱怨? -
@piwi,不,没有机会,因为
base没有默认构造函数,所以派生最多的类型必须显式构造它 -
@JamesKanze 我不得不承认“打破”钻石形状是可能的,但需要大量工作。正如人们指出的那样,对初始化程序的调用“无用”,这是我之前不知道/不理解的,我将不得不展望这种避免这种层次结构的解决方案:-/ 谢谢
-
@piwi 这只是一般规则。我确信有合法的例外。只要虚拟基类具有 no 默认构造函数,如果有人派生并且未在初始值设定项列表中提及,您应该会收到编译器错误。 (或者......将所有基类构造函数设为私有,并将您的派生类设为朋友,并且没有人可以从您的派生类派生。)
标签: c++ inheritance c++11