【发布时间】:2017-02-01 22:54:37
【问题描述】:
我有以下示例:
#include <vector>
class noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
noncopyable(noncopyable&&) = default;
noncopyable& operator=(noncopyable&&) = default;
};
class C1 : private noncopyable {
public:
C1() { }
~C1() { }
};
int main() {
std::vector<C1> v;
v.emplace_back();
return 0;
}
我认为它应该可以工作,因为C1 应该是可移动的,因为它是基类并且它没有数据成员。相反,我得到了一个错误(使用 clang++):
error: call to implicitly-deleted copy constructor of 'C1'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
.
.
.
note: in instantiation of function template specialization 'std::vector<C1, std::allocator<C1> >::emplace_back<>' requested here
v.emplace_back();
^
note: copy constructor of 'C1' is implicitly deleted because base class 'noncopyable' has a deleted copy constructor
class C1 : private noncopyable {
^
note: 'noncopyable' has been explicitly marked deleted here
noncopyable(const noncopyable&) = delete;
做一点研究 (http://en.cppreference.com/w/cpp/language/move_constructor) 发现如果有用户定义的析构函数,则不会定义隐式移动构造函数。这似乎是这里的问题,因为C1 有一个析构函数,所以没有定义移动构造函数。果然,如果我删除析构函数或将C1(C1&&) = default; 添加到C1,那么它就可以工作了。
到目前为止一切顺利。
问题是错误消息没有提到~C1() 或移动构造函数。它说它正在尝试调用复制构造函数,该构造函数在基类中被删除。所以我尝试将noncopyable 中的deleteed 函数改为defaulted,并且(惊喜!),这也解决了错误。
所以我的问题是,最后这件事与错误或纠正有什么关系?如果有析构函数,基类有没有拷贝构造函数有什么区别?
【问题讨论】:
-
尝试添加
noexcept说明符。 -
请注意“没有移动构造函数”和“有已删除的移动构造函数”之间的区别。
标签: c++ c++11 constructor