C++ 如何返回没有复制构造函数的对象

C++ 如何返回没有复制构造函数的对象,c++,c++11,copy-constructor,move-semantics,move-constructor,C++,C++11,Copy Constructor,Move Semantics,Move Constructor,我的问题涉及如何返回没有复制构造函数的对象。作为一个例子,让我们假设堆中有一些bigResource,假设我使用unique\u ptr跟踪它。现在假设我把这个资源的所有权给了一只毛虫。然后我有了一个毛毛虫,它有着巨大的资源。现在,这个CaterpillarWithBigResource将变成ButterflyWithBigResource,因此Caterpillar对象必须将所有权转移到Butterfly对象 我编写了以下代码来模拟这种情况: #include <cstdlib>

我的问题涉及如何返回没有复制构造函数的对象。作为一个例子,让我们假设堆中有一些
bigResource
,假设我使用
unique\u ptr
跟踪它。现在假设我把这个资源的所有权给了一只毛虫。然后我有了一个
毛毛虫,它有着巨大的资源
。现在,这个
CaterpillarWithBigResource
将变成
ButterflyWithBigResource
,因此
Caterpillar
对象必须将所有权转移到
Butterfly
对象

我编写了以下代码来模拟这种情况:

#include <cstdlib>
#include <iostream>
#include <memory>

class ButterflyWithBigResource {
public:

    //    If I uncomment just this line, I get an error
    //    ButterflyWithBigResource(const ButterflyWithBigResource& other) = default;

    //    If I uncomment just this line, I get an error
    //    ButterflyWithBigResource(const ButterflyWithBigResource& other) = delete;

    //   With both above lines commented out, I get no errors, and the program runs fine.

    ButterflyWithBigResource(std::unique_ptr<int>&& bigResource) :
    bigResource(std::move(bigResource)) {

    }

    const int& getResource() {
        return *bigResource;
    }

private:
    std::unique_ptr<int> bigResource;
};

class CaterpillarWithBigResource {
public:

    CaterpillarWithBigResource(int bigResource) :
    bigResource(new int(bigResource)) {

    }

    ButterflyWithBigResource toButterfly() && {
        return ButterflyWithBigResource(std::move(bigResource));
    }
private:
    std::unique_ptr<int> bigResource;
};

/*
 * 
 */
int main(int argc, char** argv) {
    CaterpillarWithBigResource caterpillarWithBigResource(5);
    ButterflyWithBigResource butterflyWithBigResource(std::move(caterpillarWithBigResource).toButterfly());
    std::cout << butterflyWithBigResource.getResource() << std::endl;
    return 0;
}
#包括
#包括
#包括
类ButterflyWithBigResource{
公众:
//如果我只取消注释这一行,我会得到一个错误
//ButterflyWithBigResource(const ButterflyWithBigResource&other)=默认值;
//如果我只取消注释这一行,我会得到一个错误
//ButterflyWithBigResource(常量ButterflyWithBigResource&其他)=删除;
//以上两行都被注释掉了,我没有收到任何错误,程序运行良好。
ButterflyWithBigResource(std::unique_ptr&&bigResource):
bigResource(标准::移动(bigResource)){
}
const int&getResource(){
返回*大资源;
}
私人:
std::唯一的资源;
};
CaterpillarWithBigResource类{
公众:
CaterpillarWithBigResource(int bigResource):
bigResource(新int(bigResource)){
}
拥有巨大资源的蝴蝶(&&{
返回ButterflyWithBigResource(std::move(bigResource));
}
私人:
std::唯一的资源;
};
/*
* 
*/
int main(int argc,字符**argv){
有较大资源的毛虫有较大资源的毛虫(5);
ButterflyWithBigResource ButterflyWithBigResource(std::move(caterpillarWithBigResource.toButterfly());

std::cout当您注释掉显式
default
delete
复制构造函数的两行时,编译器可以为您隐式生成移动构造函数(和移动赋值运算符)

通过显式
default
ing或
delete
ing复制构造函数,可以抑制移动构造函数的隐式生成

来自N3337,§12.8/9[class.copy]

如果类
X
的定义没有显式声明移动构造函数,则当且仅当
-
X
没有用户声明的复制构造函数,
-

当不再生成移动构造函数时,必须复制
toButterfly()
中的返回值,但无论您是默认还是删除了复制构造函数,该操作都会失败

如果您
default
复制构造函数,编译器将无法生成默认的复制构造函数实现,因为存在
unique_ptr
数据成员(不可复制)

当您
删除
复制构造函数时,如果通过重载解析选择它,则这是一个错误


您不必显式删除复制构造函数,因为如上所述,
unique\u ptr
数据成员的存在会隐式删除它,但是如果您想这样做,那么您还需要显式默认移动构造函数(如果您希望移动赋值起作用,还需要移动赋值操作符)


哦,好吧,那很简单。这就解决了问题。在我的真实代码中,我有
virtual~C()=默认值;
@nowigettolearnwhataheads-
X
没有用户声明的析构函数是上面列表中的第四个项目符号:)显式默认的复制构造函数是用户声明的复制构造函数?@0x499602D2是的,但不是用户提供的。我希望这些术语更容易记住,但我每次都要去查找它.BTW,要返回没有复制构造函数的对象,您需要使用复制列表初始化:
return{std::move(bigResource)}
ButterflyWithBigResource(ButterflyWithBigResource&&) = default;
ButterflyWithBigResource& operator=(ButterflyWithBigResource&&) = default;