C++:如果我不使用 move,我还需要关心复制控制吗?
C++: Need I still care copy control if I don't use move?
复制控制似乎与默认构造函数,复制构造函数,复制赋值操作符,析构函数等有关,乘以用户编写的和合成的,加上移动复制/赋值。
听起来很复杂。我发现很难记住什么东西要合成,什么时候合成。
只是想知道,如果我在构造函数或赋值操作符中不使用move,我还需要关心差异吗?
在用户代码中,几乎不需要编写析构函数,从而复制/移动构造函数和赋值操作符。这是因为您将组成支持raii的对象的类。
只有在控制非raii资源时才需要编写析构函数,例如从c风格或原始c++库导出的文件句柄或数据库连接。
在这种情况下,我们只需将资源包装在unique_ptr(带自定义删除器)或shared_ptr(同样带自定义删除器)中,就完成了。
那么我们还有两种情况:
-
多态接口的基类(不受shared_ptr控制)——在这种情况下,我们必须编写一个虚析构函数,然后可能根据默认实现实现move/copy。
-
一个可移动的类(因为它拥有一个unique_ptr,比如说?),我们希望它是可复制的。现在我们被迫实现复制操作和默认的移动操作。
还有一些其他的极端情况,比如你的类拥有一个不可复制的互斥锁。但是,如果您的类拥有互斥锁,那么要求互斥锁是可复制的可能已经是一个设计错误。无论如何,此时你应该已经熟记了复制/赋值/移动规则。
一些例子:
struct owns_a_file_movable
{
struct file_deleter {
void operator()(FILE* f) const noexcept {
fclose(f);
}
};
// RAII class now, moveable. Copy would not make sense.
std::unique_ptr<FILE, file_deleter> file_;
};
struct owns_a_file_copyable
{
struct file_deleter {
void operator()(FILE* f) const noexcept {
fclose(f);
}
};
// construct from string
owns_a_file_copyable(std::string fname)
: path_(std::move(fname))
, file_(fopen(path_, "r"), file_deleter())
{
}
// we want it to be copyable. In our case, a copy will open another
// instance of the file. so we must store the filename.
owns_a_file_copyable(owns_a_file_copyable const& r)
: path_(t.path_)
, file_(fopen(path_, "r"), file_deleter())
{}
owns_a_file_copyable& operator=(owns_a_file_copyable const& r)
{
auto tmp = r;
std::swap(path_, tmp.path_); // changed: was r.path_ which was wrong
std::swap(file_, tmp.file_);
return *this;
}
owns_a_file_copyable(owns_a_file_copyable&&) = default;
owns_a_file_copyable& operator=(owns_a_file_copyable&&) = default;
// std::string is fully RAII
std::string path_;
// RAII class now, moveable
std::unique_ptr<FILE, file_deleter> file_;
};
struct how_most_classes_should_be
{
// no destructors, copy operators, assignment or move - it's all
// generated for you.
std::string this_;
std::string that_;
std::shared_ptr<const OtherThing> shared_other_; // note - shared semantics
std::function<void()> closure_; // these are copyable too
};
阿多斯的
什么触发了什么?
// ordinary constructor
auto y = owns_a_file_copyable("/users/rhodges/foo.txt");
// copy constructor: owns_a_file_copyable(owns_a_file_copyable const&)
auto x = y;
// copy assignment: owns_a_file_copyable& operator-(owns_a_file_copyable const&)
x = y
// move-constructor: owns_a_file_copyable(owns_a_file_copyable &&)
auto z = std::move(x);
// move-assignment: owns_a_file_copyable& operator-(owns_a_file_copyable &&)
z = std::move(y);
// also move-constructor
extern owns_a_file_copyable make_file();
auto w = make_file();
// this time move-assignment
w = make_file();
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 编译器在不需要复制构造函数时关心复制构造函数
- C++:如果我不使用 move,我还需要关心复制控制吗?