C++ 返回具有唯一\u ptr成员的对象需要什么?

C++ 返回具有唯一\u ptr成员的对象需要什么?,c++,return,copy-constructor,unique-ptr,virtual-destructor,C++,Return,Copy Constructor,Unique Ptr,Virtual Destructor,假设我有一个目标: struct foo { std::unique_ptr<int> mem; virtual ~foo() = default; }; 正如可能指出的,我需要析构函数是虚拟的,因为这将是一个基类。但即使使用默认析构函数,这还不够,我仍然无法返回在函数中创建的对象 我得到一个错误: error C2280: foo::foo(const foo &): attempting to reference a deleted function

假设我有一个目标:

struct foo {
    std::unique_ptr<int> mem;
    virtual ~foo() = default;
};
正如可能指出的,我需要析构函数是虚拟的,因为这将是一个基类。但即使使用默认析构函数,这还不够,我仍然无法返回在函数中创建的对象

我得到一个错误:

error C2280: foo::foo(const foo &): attempting to reference a deleted function
有没有办法绕过这个问题?

Per

如果类X的定义未显式声明移动构造函数,则非显式构造函数将隐式声明为默认值当且仅当[…]

  • X没有用户声明的析构函数

是用户声明的析构函数。您不再有移动构造函数,因此它尝试使用复制构造函数,但无法使用,因为该构造函数已被删除,因为您有一个不可复制的成员

要返回move构造函数并保持默认构造函数的可构造性,需要添加

foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well
foo


必须添加
foo()=default的原因当您添加
foo(foo&&)=默认值时
foo(foo&&)=默认值
是一个已使用的声明构造函数,如果您有任何用户声明的构造函数,则不再提供默认构造函数


这是一个“黑客”,但您可以做的是将虚拟析构函数移动到另一个类中,然后从该类继承。这将在
foo
中为您提供一个虚拟析构函数,而无需声明它并提供所需的默认构造函数。那看起来像

struct make_virtual
{
    virtual ~make_virtual() = default;
};

struct foo : make_virtual {
    std::unique_ptr<int> mem;
};
struct使_虚拟化
{
virtual~make_virtual()=默认值;
};
struct foo:make_virtual{
std::唯一的ptr 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;
}
structfoo{
独特的记忆;
foo()=默认值;
foo(const foo©);
virtual~foo()=默认值;
};
foo::foo(constfoo©):mem(newint(*copy.mem)){
foo make_foo(){
foo结果;
result.mem=使_唯一();
返回结果;
}

尝试添加
foo()=默认值
foo(foo&&)=默认值
foo&operator=(foo&&)=默认值。如果定义了移动赋值运算符“复制构造函数/赋值运算符”或“析构函数”,则不会隐式生成移动构造函数。@user463035818最后一条错误消息是/usr/include/c++/6/bits/unique\u ptr.h:359:7:注意:此处声明的是unique\u ptr(const unique\u ptr&)=delete@NathanOliver哦,对了,我太习惯于先修复第一件事了,所以我忽略了它。我总是忘记默认析构函数和默认析构函数是不同的。没有别的方法可以让默认析构函数虚拟化了吗?@ JoaAthMeEE No.C++让你第一次为它付费(基类)。在派生类中,
~derived()
将隐式虚拟。@JonathanMee实际上我刚刚为您添加了一个“hack”。@JonathanMee您使用的编译器和版本是什么<代码>结果
应被视为一个右值,因为它是一个本地自动对象。@JonathanMee这能为您解答所有问题吗?
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;
}