首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与智能指针相关的C++移动语义与复制构造器和赋值操作符

与智能指针相关的C++移动语义与复制构造器和赋值操作符
EN

Stack Overflow用户
提问于 2014-07-23 08:05:10
回答 2查看 1.8K关注 0票数 1

我试图找出何时使用移动语义,以及何时使用复制构造函数和赋值操作符作为经验规则。您在类中使用的指针类型(如果有的话)似乎受到此答案的影响,因此我包含了以下内容。

No指针--基于this答案,如果您有一个包含int和string等基本类型的this类,则不需要编写自定义移动或复制构造函数和运算符。

unique-ptr -基于this应答,当使用移动语义时,unique_ptr比shared_ptr更适合,因为资源只能有一个unique_ptr。

shared_ptr -同样,如果使用复制语义,shared_ptr似乎是可行的。对象可以有多个副本,所以有一个指向资源的共享指针对我来说是有意义的。但是,unique_ptr通常比shared_ptr更可取,因此,如果可以的话,请避免使用此选项。

但是:

  1. 我什么时候应该使用移动语义?
  2. 我什么时候应该使用复制语义?
  3. 这两样我都用过吗?
  4. 我是否应该使用none并依赖默认的复制构造函数和赋值操作符?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-23 08:17:06

如名称所示,当资源必须存在一个所有者时,请使用unique_ptr。禁用了unique_ptr的复制构造函数,这意味着它的两个实例不可能存在。然而,它是可移动的..。这很好,因为这允许所有权的转移。

另外,如名称所示,shared_ptr表示资源的共享所有权。然而,两个智能指针之间还有另一个区别:unique_ptrunique_ptr是其类型签名的一部分,但它不是shared_ptr类型签名的一部分。这是因为shared_ptr使用“类型擦除”来“擦除删除项的类型”。还要注意,shared_ptr也可以被移动到转移所有权(比如unique_ptr)。

我什么时候应该使用移动语义?

尽管可以复制shared_ptr,但在进行所有权转移时(而不是创建新的引用),您可能希望将它们移动。您必须对unique_ptr使用移动语义,因为所有权必须是唯一的。

我什么时候应该使用复制语义?

对于智能指针,应该使用复制来增加shared_ptr的引用计数。(如果您不熟悉引用计数的概念,研究引用计数垃圾收集。)

这两样我都用过吗?

是。如上所述,可以复制和移动shared_ptr。复制表示增加引用计数,而移动仅表示所有权的转移(引用计数保持不变)。

我是否应该使用none并依赖默认的复制构造函数和赋值操作符?

当您想按成员复制对象时。

票数 6
EN

Stack Overflow用户

发布于 2014-07-23 08:52:34

  1. 我什么时候应该使用移动语义? 我想你的意思是,“我什么时候应该给我的班级一个移动构造函数?”答案是,每当移动这种类型的对象很有用时,默认的move构造函数就不能正确地完成任务。当资源从一个对象转移到另一个对象时,移动是很有用的。例如,移动对std::string很有用,因为它允许从临时对象复制对象,而不必重新分配和复制它们的内部资源,而只需将资源从一个移动到另一个。许多类型将从中受益。另一方面,移动对std::unique_ptr是有用的,因为它是通过值传递std::unique_ptr而不违反其“唯一所有权”的唯一方法。
  2. 我什么时候应该使用复制语义? 我再说一遍,你的意思是,“什么时候我应该给我的班级一个副本构造函数?”每当您需要创建对象的副本时,内部资源都会在它们之间进行复制,而默认的复制构造函数没有正确地完成任务。复制对于几乎任何类型都是有用的,除了那些必须对内部资源强制执行唯一所有权的std::unique_ptr
  3. 这两样我都用过吗? 大多数情况下,类都应该同时提供复制和移动语义。最常见的类应该是可复制的和可移动的。可复制提供了按值传递对象的标准语义。可移动允许通过值传递临时对象时获得的优化。这意味着必须提供副本或移动构造函数,这取决于默认构造函数是否执行适当的操作。
  4. 我是否应该使用none并依赖默认的复制构造函数和赋值操作符? 默认的复制和移动构造函数只分别对类的每个成员进行复制或移动。如果这种行为适合复制和移动您的类,那就太好了。在大多数情况下,这应该足够好。例如,如果我有一个包含std::string的类,默认的复制构造函数将复制字符串,默认的移动构造函数将将字符串的资源移动到新对象--两者都执行适当的任务。如果您的类包含一个std::unique_ptr,那么复制将根本无法工作,而且您的类只能移动。这可能是您想要的,或者您可能希望实现一个执行资源深度复制的副本构造函数。在实现复制/移动构造函数时,最重要的情况是类本身执行资源管理(例如,使用newdelete )。如果是这样的话,默认的构造函数在管理这些资源方面几乎永远不会做得很好。

这里的一切都同样适用于赋值运算符。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24904979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档