具有不可复制成员的复制赋值运算符
Copy assignment operator with non-copyable members
假设我有一个 class A
只有一个构造函数:
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
我还有一个 class B
包含一个 A
的实例并定义复制构造函数如下:
struct B
{
B() = default;
B(const B& other) : _a{} {}
A _a;
};
这里 B
的构造函数只是用 A
的新实例初始化 _a
。但是,我怎么能为 B
编写赋值运算符(因为我不能“重新初始化”_a
)?
如果您希望operator=
创建一个类似于复制构造函数的全新A
,并且如果动态分配可行,您可以使用std::unique_ptr<A>
作为成员:
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
struct B
{
B() : _a{std::make_unique<A>()} {}
B(const B& other) : _a{std::make_unique<A>()} {}
B& operator=(const B& other) {
_a = std::make_unique<A>();
return *this;
}
std::unique_ptr<A> _a;
};
不过,如果 B
有一个不可复制(不可移动)的成员,那么如果 B
也是不可复制(不可移动)的话,最不奇怪。
根据classA
的定义,A
的实例是不可复制的,也是不可移动的。所以,我接受了@463035818_is_not_a_number.
的回答
这是另一个答案,它假设 A
可以移动,只是为了完整性或者它可能对某人有用。
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&&) = default;
A& operator=(A&&) = default;
};
struct B
{
B() = default;
B(const B&) : _a{} {}
B& operator=(B other)
{
std::swap(_a, other._a);
return *this;
}
A _a;
};
假设我有一个 class A
只有一个构造函数:
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
我还有一个 class B
包含一个 A
的实例并定义复制构造函数如下:
struct B
{
B() = default;
B(const B& other) : _a{} {}
A _a;
};
这里 B
的构造函数只是用 A
的新实例初始化 _a
。但是,我怎么能为 B
编写赋值运算符(因为我不能“重新初始化”_a
)?
如果您希望operator=
创建一个类似于复制构造函数的全新A
,并且如果动态分配可行,您可以使用std::unique_ptr<A>
作为成员:
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
struct B
{
B() : _a{std::make_unique<A>()} {}
B(const B& other) : _a{std::make_unique<A>()} {}
B& operator=(const B& other) {
_a = std::make_unique<A>();
return *this;
}
std::unique_ptr<A> _a;
};
不过,如果 B
有一个不可复制(不可移动)的成员,那么如果 B
也是不可复制(不可移动)的话,最不奇怪。
根据classA
的定义,A
的实例是不可复制的,也是不可移动的。所以,我接受了@463035818_is_not_a_number.
这是另一个答案,它假设 A
可以移动,只是为了完整性或者它可能对某人有用。
struct A
{
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&&) = default;
A& operator=(A&&) = default;
};
struct B
{
B() = default;
B(const B&) : _a{} {}
B& operator=(B other)
{
std::swap(_a, other._a);
return *this;
}
A _a;
};