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;