问题标签 [copy-and-swap]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 根据构造函数实现 C++ 赋值运算符
背景
假设您想在 C++ 中实现一个资源管理类。您不能使用零规则或五个默认规则,因此您实际上需要实现复制和移动构造函数、复制和移动赋值运算符和析构函数。在这个问题中,我将Box
用作示例,但这可以适用于许多不同的类型。
(请注意,更好的Box
实现将具有更多的特性,例如noexcept
和constexpr
函数、explicit
基于构造函数的转发构造value_type
函数、分配器支持等;这里我正在实现问题和测试所必需的东西。它还可以使用 保存一些代码std::unique_ptr
,但这会使它成为一个不太清楚的例子)
请注意,赋值运算符彼此共享大量代码,与它们各自的构造函数和析构函数共享。如果我不想让分配到从Box
en 移动,这会有所减轻,但在更复杂的类中会更明显。
题外话:复制和交换
处理此问题的一种标准方法是使用Copy-And-Swap Idiom(在此上下文中也称为“四半规则”)swap
,如果是,它还可以为您提供强有力的异常保证nothrow
:
这允许您只编写一个赋值运算符(other
如果可能,按值取值让编译器将另一个移动到参数,并在必要时为您进行复制),并且该赋值运算符很简单(假设您已经拥有swap
)。但是,正如链接文章所说,这存在诸如在操作期间进行额外分配和保留内容的额外副本等问题。
理念
我以前没有见过的是我称之为销毁和初始化赋值运算符的东西。既然我们已经在构造函数中完成了所有工作,并且对象的分配版本应该与复制构造的对象相同,为什么不使用构造函数,如下所示:
这仍然像 Copy-and-Swap 那样进行额外分配,但仅在复制分配情况下而不是在移动分配情况下,并且它在销毁 的一个副本后进行T
,因此它不会在资源限制下失败。
问题
- 以前是否有人提出过这个建议,如果有,我可以在哪里阅读更多相关信息?
- 在某些情况下,这个 UB 是否
Box
是其他东西的子对象,或者它是否允许销毁和重建子对象? - 这有什么我没有提到的缺点吗,比如不
constexpr
兼容? - 当您不能只使用它们时,是否还有其他选项可以避免赋值运算符代码重用,例如这个和四点半规则
= default
?
c++ - 类使用(复制和交换)的复制赋值运算符和普通工具给出不同的结果
在 C++ Primer 5th,13.3 Swap 中,练习 13.31。问题需要给类Has_ptr一个 < 运算符并创建一个元素很少的向量,然后对向量进行排序。类的实现如上。
Has_ptr有 2 个数据成员
- 字符串指针ptr,指向动态内存
- 诠释我
Has_pt r 类具有以下复制控制成员
- 构造函数接受一个字符串和一个 int。
- copy_constructor,实现为类行为像值。
- 删除由ptr分配的动态内存的析构函数。
我为复制分配运算符尝试了两种实现。一个我首先创建临时字符串指针变量 x 来保存 RHS 指针,然后删除 LHS 指针,最后将 RHS 分配给 LHS。但是,这种实现使代码无法编译。
第二种实现使用了复制和交换。这使得代码编译并碎片化运行。
我的主要功能如下
第二种实现在编译器时不产生错误/警告消息并产生以下输出
第一个实现产生以下错误消息