第17项:了解特殊成员函数的生成。
仅针对缺少的分类生成移动操作 明确声明移动操作,复制操作, 或者是一个析构函数。
现在,当我提到移动操作移动构造时
或移动 - 分配数据成员或基类,有
并不保证会实际采取行动
实际上,“成员行动”更像是成员
移动请求,因为未启用移动的类型(...)
将通过他们的复制操作“移动”。
但是,我无法在我的环境中验证它们。
// compiled
#include <iostream>
using namespace std;
class Base {
public:
~Base() {}
};
int main() {
Base a, c;
Base b(move(a));
c = move(b);
// explicitly destructor does not disable
// default move constuctor and move assignment operator
return 0;
}
class Base {
public:
Base() {}
Base(Base& b) {}
~Base() {}
};
class Num {
private:
Base b;
};
int main() {
Num a, c;
c = move(a); // passed
Num b(move(c)); // error
// explicitly Base::Base(Base& b) disable default move
// move conctructor.
// Num's default move constructor can not find any move
// constructor for member object Base b, which lead to an
// error. Num's default move constructor does not "moved"
// Base b via their copy operations which is declared.
return 0;
}
第一个断言可能因不同环境而异,但第二个断言几乎是错误的 我很困惑。 请帮帮我。
答案 0 :(得分:0)
class Base {
public:
~Base() {}
};
因为Base
具有用户声明的析构函数,所以它根本没有移动构造函数或移动赋值运算符。行
Base b(move(a));
c = move(b);
实际上分别调用了复制构造函数和复制赋值运算符。
class Base {
public:
Base() {}
Base(Base& b) {}
~Base() {}
};
class Num {
private:
Base b;
};
同样,Base
根本没有移动构造函数。但是,Num
确实有一个隐式声明的移动构造函数,因为Num
本身并不声明任何特殊的成员函数。但是,它被隐式定义为已删除,因为默认定义将是格式错误的:
Num::Num(Num&& n) : b(std::move(n.b)) {}
// Cannot convert rvalue of type `Base` to `Base&`
// for the copy constructor to be called.
请注意,b
的“移动”会尝试使用复制构造函数,但它不能。