c++ - 依赖项没有复制 ctor 或赋值运算符时的 C++ 初始化程序列表
问题描述
方法一
我有一些 Foo 类型,它内部包含一个 std::mutex。
class Foo {
std::mutex m_;
};
我写了另一个类吧。Bar 有 Foo 作为成员和构造函数,如下所示(注意 - 此代码无法编译):
class Bar {
Bar(Foo foo) : foo(foo) {}
...
private:
Foo foo;
};
我的 IDE 抱怨:
调用 Foo 的隐式删除的复制构造函数。'Foo' 的复制构造函数被隐式删除,因为字段 'm_' 具有已删除的复制构造函数
方法二
所以我试着做这样的任务:
class Bar {
Bar(Foo fooIn) { foo = fooIn; }
...
private:
Foo foo;
};
但这也说明:
无法分配“Foo”类型的对象,因为它的复制赋值运算符被隐式删除
方法 3(使用指针)
我可以让它工作的唯一方法是这样的:
class Foo {
private:
std::mutex m_;
};
class Bar {
Bar(std::unique_ptr<Foo> fooIn) : foo(std::move(fooIn)) {}
private:
std::unique_ptr<Foo> foo;
};
我了解智能指针有助于内存管理。但是让我们把这个功能放在一边。
在我上面的例子中,不使用智能指针和使用智能指针的主要区别在于智能指针具有间接性——它指向堆上的一个对象。对?
理解这一点的正确心智模型是什么?是不是因为 Foo 有一个已删除的复制构造函数和已删除的复制分配,所以我唯一的选择是在堆上构造它,然后通过间接(通过指针)工作?
那是对的吗?还是我完全关闭了?
解决方案
是不是因为 Foo 有一个已删除的复制构造函数和已删除的复制分配,所以我唯一的选择是在堆上构造它,然后通过间接(通过指针)工作?
关闭,但不完全。
因为互斥体不可复制,所以默认情况下 Foo 也不可复制。您正在尝试复制,这是不可能的。
使用间接引用存储在别处的 Foo 是可能的。但是 Foo 没有必要拥有动态存储来实现这一点。不可复制性也不意味着需要间接……除非您想防止不可复制性传播到封闭类。
互斥锁唯一的构造函数是默认构造函数。因此,您可以合理地做的只是默认初始化 Foo。一个最小的例子:
struct Bar {
Foo foo;
// no need to declare the default constructor
// it is generated implicitly
};
Bar bar; // this just works
推荐阅读
- reactjs - 如何根据用户输入更新右侧的结果
- django - 带有按钮和表单的 TemplateColumn 仅返回记录名称而不是内容
- mysql - SQL中表中的重复记录具有两个相同的列值和一个不同的值
- python - 如何告诉 CMake 在 manylinux 中使用哪个 Python 版本?
- google-bigquery - Google CLI 未创建 Transfer Service 且未显示详细错误
- vba - PPT VBA,将所有打开的PPT另存为PDF
- networking - 智能手机中的数据链路层和物理层设备
- wso2 - 无法在 WSO2 API Manager 3.1.0 中启用 MailtoSender
- reactjs - 如何在另一个组件中使用一个组件的状态?独立组件(React)
- karate - 如何删除空手道中的多个数组对象?