Return 具有 unique_ptr 成员的对象需要什么?
What do I Need to Return an Object with a unique_ptr Member?
假设我有这个对象:
struct foo {
std::unique_ptr<int> mem;
virtual ~foo() = default;
};
我无法再 return 在函数中创建 foo
对象:
foo make_foo() {
foo result;
result.mem = std::make_unique<int>({});
return result;
}
正如可能指出的那样,我需要析构函数是虚拟的,因为这将是一个基础 class。但是即使我使用默认的析构函数,这还不够,我仍然不能 return 在函数中创建的对象。
我收到错误:
error C2280: foo::foo(const foo &): attempting to reference a deleted function
有没有办法解决这个问题?
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if [...]
- X does not have a user-declared destructor.
自
virtual ~foo() = default;
是用户声明的析构函数,您不再有移动构造函数,因此它尝试使用复制构造函数但不能,因为它已被删除,因为您有一个不可复制的成员。
要取回移动构造函数,并保持默认构造函数,您需要添加
foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well
到foo
在添加 foo(foo&&) = default;
时必须添加 foo() = default;
的原因是 foo(foo&&) = default;
是一个已使用声明的构造函数,如果您有任何用户声明的构造函数,则默认构造函数不再提供。
这是一个“hack”,但您可以将虚拟析构函数移至另一个 class,然后从中继承。这将为您提供 foo
中的虚拟析构函数,而无需声明它并为您提供所需的默认构造函数。那看起来像
struct make_virtual
{
virtual ~make_virtual() = default;
};
struct foo : make_virtual {
std::unique_ptr<int> mem;
};
提供您自己的复制构造函数和默认构造函数,将成员转换为共享指针或提供移动构造函数。一种可能的解决方案:
struct foo {
unique_ptr<int> mem;
foo() = default;
foo(const foo& copy);
virtual ~foo() = default;
};
foo::foo(const foo& copy) : mem(new int(*copy.mem)) {}
foo make_foo() {
foo result;
result.mem = make_unique<int>();
return result;
}
假设我有这个对象:
struct foo {
std::unique_ptr<int> mem;
virtual ~foo() = default;
};
我无法再 return 在函数中创建 foo
对象:
foo make_foo() {
foo result;
result.mem = std::make_unique<int>({});
return result;
}
正如可能指出的那样,我需要析构函数是虚拟的,因为这将是一个基础 class。但是即使我使用默认的析构函数,这还不够,我仍然不能 return 在函数中创建的对象。
我收到错误:
error C2280: foo::foo(const foo &): attempting to reference a deleted function
有没有办法解决这个问题?
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if [...]
- X does not have a user-declared destructor.
自
virtual ~foo() = default;
是用户声明的析构函数,您不再有移动构造函数,因此它尝试使用复制构造函数但不能,因为它已被删除,因为您有一个不可复制的成员。
要取回移动构造函数,并保持默认构造函数,您需要添加
foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well
到foo
在添加 foo(foo&&) = default;
时必须添加 foo() = default;
的原因是 foo(foo&&) = default;
是一个已使用声明的构造函数,如果您有任何用户声明的构造函数,则默认构造函数不再提供。
这是一个“hack”,但您可以将虚拟析构函数移至另一个 class,然后从中继承。这将为您提供 foo
中的虚拟析构函数,而无需声明它并为您提供所需的默认构造函数。那看起来像
struct make_virtual
{
virtual ~make_virtual() = default;
};
struct foo : make_virtual {
std::unique_ptr<int> mem;
};
提供您自己的复制构造函数和默认构造函数,将成员转换为共享指针或提供移动构造函数。一种可能的解决方案:
struct foo {
unique_ptr<int> mem;
foo() = default;
foo(const foo& copy);
virtual ~foo() = default;
};
foo::foo(const foo& copy) : mem(new int(*copy.mem)) {}
foo make_foo() {
foo result;
result.mem = make_unique<int>();
return result;
}