Muh*_*eed 1 c++ pointers smart-pointers move-semantics c++11
我试图找出何时使用移动语义以及何时使用复制构造函数和赋值运算符作为经验法则.你的类中使用的指针类型(如果有的话)似乎受到这个答案的影响,所以我已经包含了这个.
没有指针 - 基于这个答案,如果你有一个包含int和string等基本类型的POD类,则不需要编写自定义移动或复制构造函数和运算符.
unique-ptr - 基于这个答案,当使用移动语义时,unique_ptr比shared_ptr更合适,因为资源只能有一个unique_ptr.
shared_ptr - 同样,如果使用复制语义,shared_ptr似乎还有很长的路要走.可以有多个对象副本,因此拥有一个指向资源的共享指针对我来说很有意义.但是,unique_ptr通常优先于shared_ptr,因此如果可以,请避免使用此选项.
但:
如名称所示,unique_ptr当资源必须只有一个所有者时使用.复制构造函数unique_ptr被禁用,这意味着它的两个实例不可能存在.但是,它是可移动的...这很好,因为这允许所有权的转移.
同样如名称所示,shared_ptr表示资源的共享所有权.但是,两个智能指针之间还存在另一个区别:Deletera unique_ptr是其类型签名的一部分,但它不是类型签名的一部分shared_ptr.那是因为shared_ptr使用"类型擦除"来"删除删除者的类型".另请注意,shared_ptr也可以移动转让所有权(如unique_ptr.)
我什么时候应该使用移动语义?
虽然shared_ptr可以复制,但您可能希望在进行所有权转移时移动它们(而不是创建新的引用).您有义务使用移动语义unique_ptr,因为所有权必须是唯一的.
我什么时候应该使用复制语义?
在智能指针的情况下,您应该使用复制来增加shared_ptrs 的引用计数.(如果您不熟悉引用计数的概念,则研究参考计算垃圾收集.)
我应该同时使用两者吗?
是.如上所述,shared_ptr可以复制和移动.复制表示递增引用计数,而移动仅表示所有权转移(引用计数保持不变).
我应该使用none并依赖默认的复制构造函数和赋值运算符吗?
如果要创建对象的逐个成员副本.
我什么时候应该使用移动语义?
我认为你的意思是,"我应该什么时候给我的班级一个移动构造函数?" 答案是,只要移动此类型的对象很有用,并且默认移动构造函数无法正确执行该任务.将资源从一个对象转移到另一个对象有一些好处时,移动很有用.例如,移动很有用,std::string因为它允许从临时对象复制对象,而无需重新分配和复制其内部资源,而只需将资源从一个移动到另一个.许多类型都会从中受益.另一方面,移动是有用的,std::unique_ptr因为它是在std::unique_ptr不违反其"唯一所有权"的情况下传递值的唯一方法.
我什么时候应该使用复制语义?
再一次,我认为你的意思是,"我什么时候应该给我的班级一个复制构造函数?" 每当您需要能够复制对象时,在它们之间复制内部资源,并且默认的复制构造函数不能正确地完成工作.复制几乎对任何类型都有用,除了那些std::unique_ptr必须强制对内部资源的唯一所有权.
我应该同时使用两者吗?
您的类应该在大多数情况下提供复制和移动语义.最常见的类应该是可复制的和可移动的.可复制提供了按值传递对象的标准语义.可移动允许通过值传递临时对象时可以获得的优化.这是否意味着必须提供副本或移动构造函数取决于默认构造函数是否执行适当的操作.
我应该使用none并依赖默认的复制构造函数和赋值运算符吗?
默认的复制和移动构造函数只是分别对类的每个成员进行复制或移动.如果这种行为适合复制和移动你的课程,那就太好了.大多数时候,这应该足够好了.例如,如果我有一个包含a的类std::string,则默认的复制构造函数将复制该字符串,并且默认的移动构造函数会将字符串的资源移动到新对象 - 两者都执行相应的工作.如果您的班级包含a std::unique_ptr,则复制将无法正常工作,您的班级将只能移动.这可能是您想要的,或者您可能希望实现执行资源深层副本的复制构造函数.您应该实现复制/移动构造函数的最重要的情况是您的类本身执行资源管理(例如,使用new和delete).如果是这种情况,默认构造函数几乎从不会很好地管理这些资源.
这里的所有内容都类似于赋值运算符.
| 归档时间: |
|
| 查看次数: |
1377 次 |
| 最近记录: |