gpt4 book ai didi

C++:如果我不使用 move ,我还需要关心复制控制吗?

转载 作者:搜寻专家 更新时间:2023-10-31 01:34:32 24 4
gpt4 key购买 nike

复制控制似乎与默认构造函数、复制构造函数、复制赋值运算符、析构函数等有关,乘以用户编写的和合成的,加上 move 复制/赋值。

听起来很复杂。我发现很难记住将合成什么以及何时合成。

只是想知道,如果我不在构造函数或赋值运算符中使用 move ,我还需要关心它们之间的区别吗?

最佳答案

在用户代码中,您几乎不需要编写析构函数,因此也不需要复制/move 构造函数和赋值运算符。这是因为您将组合启用 RAII 的对象的类。

我们唯一需要编写析构函数的情况是控制非 RAII 资源,例如从 C 风格或原始 C++ 库导出的文件句柄或数据库连接。

在这种情况下,我们只需将资源包装在 unique_ptr(使用自定义删除器)或 shared_ptr(同样,使用自定义删除器)中,我们就完成了。

这给我们留下了 2 个场景:

  1. 多态接口(interface)的基类(不受 shared_ptr 控制)- 在这种情况下,我们必须编写虚拟析构函数,然后可能根据默认实现实现 move/复制。

  2. 一个可 move 的类(因为它拥有一个 unique_ptr,比如说?)并且我们希望它是可复制的。现在我们被迫执行复制操作并默认执行 move 操作。

还有一些其他极端情况,例如如果您的类拥有一个不可复制的互斥量。但是,如果您的类(class)拥有互斥锁,则要求它可复制可能已经是一个设计错误。无论如何,此时您应该已经牢记复制/赋值/move 规则。

一些例子:

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++:如果我不使用 move ,我还需要关心复制控制吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39313996/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com