使用特殊的复制赋值运算符而不是简单的析构函数和就地构造函数的原因

2023-11-29

我有一个有自己的资源管理的课程:

class Lol
{

private:
  // This is data which this class allocates
  char *mName = nullptr;

public:
    Lol(std::string str) // In constructor just copy data from string
    {
        auto cstr = str.c_str();
        auto len = strlen(cstr);
        mName = new char[len + 1];
        strcpy(mName, cstr);
    };

    ~Lol() // And of course clean up
    {
        delete[] mName;
    }
}

我实现了复制构造函数,它只复制托管数据:

    Lol(const Lol &other)
    {
        auto cstr = other.mName;
        auto len = strlen(cstr);
        mName = new char[len + 1];
        strcpy(mName, cstr);
    };

我还需要实现复制赋值运算符。我刚刚这样做了:

    Lol &operator=(const Lol &other)
    {
        if (this == &other)
        {
            return *this;
        }

        // Clean up my resources
        this->~Lol();
 
        // And copy resources from "other" using already implemented copy constructor
        new (this) Lol(other);
    }

看起来这个复制赋值运算符适用于所有类。为什么复制赋值运算符中需要有另一个代码?它的用例是什么?


如果构造函数抛出异常,则必须捕获异常并以某种方式恢复(通过调用某个构造函数,可能是默认构造函数),这使得这变得不太优雅。未能调用构造函数将导致双重破坏和UB。

如果您从此类继承,或者将其用作[[no_unique_address]]成员变量:

[basic.life]/8.4

对象 o1 可以透明地被对象 o2 替换,如果: ...

— o1 和 o2 都不是潜在重叠的子对象...

and [intro.object]/7

潜在重叠的子对象是:

— 基类子对象,或者

— 使用 no_unique_address 属性声明的非静态数据成员。

这本身不是 UB,但如果你的对象不是透明可更换,重建的对象必须是std::launder在使用之前进行ed,这是不切实际的(例如,如果它是一个自动变量,那么自动销毁将会发生,而无需std::launder → UB).

C++17 还有更多限制。你还需要std::launder如果您的类包含常量或引用成员(C++17 [basic.life]/8.3).


如果您正在寻找通用赋值运算符,那么这里就有一个。它被称为复制和交换习语。看哪:

MyClass &operator=(MyClass other) noexcept
{
    std::swap(x, other.x); // Swap every member here.
    return *this;
}

这充当复制和移动赋值(如果您有各自的构造函数),并提供强大的异常保证(如果复制抛出,目标对象不变)。

(据我所知)唯一不能开箱即用的情况是类在某处(可能在其内部)维护一个指向自身的指针。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用特殊的复制赋值运算符而不是简单的析构函数和就地构造函数的原因 的相关文章

  • 捕获 .aspx 和 .ascx 页面中的异常

    问题说明了一切 请看以下示例代码 ul li li ul
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 如何向 Mono.ZeroConf 注册服务?

    我正在尝试测试 ZeroConf 示例http www mono project com Mono Zeroconf http www mono project com Mono Zeroconf 我正在运行 OpenSuse 11 和 M
  • MVC 5 中具有 ASP.NET Identity 的 Autofac 不会验证 OWIN 管道中的安全标记

    我在 MVC 5 中设置了 AutoFac 来与 ASP NET Identity 一起使用 表面上一切似乎都工作正常 即用户可以创建帐户并登录 但后来我发现 当安全标记更改时 用户不会注销 通过在 AspNetUsers 表中进行暴力破解
  • C# 根据当前日期传递日期时间值

    我正在尝试根据 sql server 中的两个日期获取记录 Select from table where CreatedDate between StartDate and EndDate我通过了5 12 2010 and 5 12 20
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • ASP.NET Core 中间件与过滤器

    在阅读了 ASP NET Core 中间件之后 我对何时应该使用过滤器以及何时应该使用中间件感到困惑 因为它们似乎实现了相同的目标 什么时候应该使用中间件而不是过滤器 9频道有一个关于此的视频 ASP NET 怪物 91 中间件与过滤器 h
  • 读取依赖步行者输出

    I am having some problems using one of the Dlls in my application and I ran dependency walker on it i am not sure how to
  • Unity3D - 将 UI 对象移动到屏幕中心,同时保持其父子关系

    我有一个 UI 图像 它的父级是 RectTransform 容器 该容器的父级是 UI 面板 而 UI 面板的父级是 Canvas 我希望能够将此 UI 图像移动到屏幕中心 即画布 同时保留父级层次结构 我的目标是将 UI 图像从中心动画
  • 在哪里可以找到 Microsoft.Build.Utilities.v3.5

    如何获取 Microsoft Build Utilities v3 5 我正在使用 StyleCop 4 7 Stylecop dll 中的 StyleCop msbuild 任务似乎依赖于 Microsoft Build Utilitie
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • 如何在C#中控制datagridview光标移动

    我希望 datagridview 光标向右移动到下一列 而不是在向单元格输入数据后移动到下一行 我试图通过 dataGridView1 KeyDown 事件捕获键来控制光标 但这并不能阻止光标在将数据输入到单元格后移动到下一行 提前感谢你的
  • ContentDialog Windows 10 Mobile XAML - 全屏 - 填充

    我在项目中放置了一个 ContentDialog 用于 Windows 10 上的登录弹出窗口 当我在移动设备上运行此项目时 ContentDialog 未全屏显示 并且该元素周围有最小的填充 在键盘上可见 例如在焦点元素文本框上 键盘和内
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐

  • 如何将 simulink 文件转换为 XML

    我需要将 Simulink 文件 mdl 转换为 XML 文件 经过任何搜索后 我没有找到任何内容来帮助我解决此问题 您知道 Java 中的某种方法或现成的解决方案吗 从 R2008b 开始 您可以使用以下命令将 mdl 文件导出到 xml
  • Angular 表单 - 访问子组件模板中的 FormArray

    我有一个需要几个组件FormControls and FormArrays 作为输入 我正在访问FormControl来自子组件的 s 如下所示 formControl control 这工作得很好 但我找不到一种方法来做同样的事情Form
  • 将 dd/mm/yy 和 dd/mm/yyyy 转换为日期

    我有一些字符向量 其中包含各种格式的日期 如下所示 dates lt c 23 11 12 20 10 2012 22 10 2012 23 11 12 我想将它们转换为日期 我已经尝试了 lubridate 包中非常好的 dmy 但这不起
  • 手动对整数列表进行排序

    我对编程还很陌生 我只学习了几个星期的Python 最近有人给我一个练习 要求我生成一个整数列表 然后在单独的列表中手动将数字从最低到最高排序 import random unordered list range 10 ordered lo
  • 虚拟 COM 端口还是使用原始端点?

    我正在使用 USB 控制器和代码示例在微控制器中开发软件来实现虚拟 COM 端口 它的实现是一个来回传输数据的设备 我正在考虑使用 2 个批量端点 在我的计算机中使用 libusb 来读取和写入它们 虚拟 COM 的优点是不需要 libus
  • 通过 Outlook 在 R 中发送电子邮件 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 如何在 R 中通过 Outlook 发送电子邮件 所有的例子sendmailR使用 Gmail 服务器 但我不能这样做 您可以使用RDCOMClient包从 R 中访问 COM
  • SQL Server LocalDB 实例无法启动(自动)

    我有一个 WPF 应用程序连接到 SQL Server 2014 Express LocalDB 即本地数据库 mdf数据库文件 该应用程序使用 Entity Framework Core 库版本 7 0 0 rc1 final 这是我正在
  • JsonConstructor 在 IEnumerable 属性上失败?

    因此 使用访问器设置可枚举效果非常好 public class SetEnumerableWithAccessor public IEnumerable
  • React 中使用鼠标滚轮缩放图像

    所以我正在尝试重制这个版本 取自并修改自这个帖子 在 React 中使用鼠标滚轮进行图像缩放 问题是 即使在 React 中使用相同的数学和逻辑 它也不能完美地工作 我不知道为什么 图像似乎没有在光标所在的位置缩放 这是我的组件 impor
  • 如何使用saxon内置目录功能

    我下载了 SaxonHE9 4 0 6J 并希望在 CLI 上处理 XHTML 然而 Saxon 尝试从 W3C 加载 DTD 并且每个简单命令都需要花费太多时间 我有 xml 目录 我通过设置指向目录文件的 env 变量成功地将其与 xm
  • vec_sld 字节序敏感吗?

    我正在开发具有核心加密功能的 PowerPC 机器 我在使用内置函数将 AES 密钥扩展从大端移植到小端时遇到问题 大端有效 但小端无效 下面的算法是一个片段中呈现的IBM 博客文章 我认为我已将问题隔离到下面的第 2 行 typedef
  • 防止Oracle中重复插入数据

    我有表 COBA 有 3 个字段 它们是 NOMER NAMA KETERANGAN 表中存在这样的数据 我想向该表插入另一个值 但是如何防止在 Oracle 中重复插入查询数据 我尝试使用 WHERE NOT EXIST 这是我的查询 I
  • 将鞋子集成到 Aptana Studio RadRails 中

    我怎样才能运行我的Carpet直接从 Aptana Studio 与 RadRails 应用程序 将 Shoes exe 设置为 VM 解释器将不起作用 如果 Ruby 项目中有该文件 则可以执行以下操作 转到运行 gt 外部工具 gt 外
  • 如何同时打开 Pygame 窗口和 Tkinter 窗口?

    我正在使用 Pygame 模块制作一个简单的游戏 我需要在 Pygame 窗口旁边打开 Tkinter 窗口 每当我尝试打开两个窗口时 第二个窗口只有在我杀死第一个窗口后才会打开 现在 我能想到的唯一解决方案是使用多线程 但是 我无法实施它
  • ld:在 MacOS / nasm 上找不到架构 x86_64 的符号

    我是汇编编程新手 所以我提前道歉 我在链接第一个时遇到问题Hello world汇编程序在MacOS and nasm section data text db Hello World 10 section text global star
  • 在django中删除带有表单的对象

    我正在显示一张桌子 每行都应该有一个删除按钮 用于从表中删除元素 我的问题是 我不确定如何将元素的 id 传递给视图 html for post in posts div h3 Zuletzt ausgew hlt h3 p publish
  • Rails Asset Pipeline - 错误的指纹

    我的 Rails 4 应用程序有new html erb其中引用了form html erb app assets templates jobs new html erb
  • c 中对“getline”的未定义引用

    我正在学习在 C 编程中使用 getline 并尝试了以下代码http crasseux com books ctutorial getline html include
  • 为什么 Python 3 不向后兼容? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我了解到 Python 3
  • 使用特殊的复制赋值运算符而不是简单的析构函数和就地构造函数的原因

    我有一个有自己的资源管理的课程 class Lol private This is data which this class allocates char mName nullptr public Lol std string str I