C++ Rule of Three/Five

文章目录

  • 问题
    • 特殊的成员函数
      • 隐式的定义
  • 资源管理
    • 显示定义
    • 异常安全
    • 不可复制资源
  • rule of three
  • rule of five
  • 参考

问题

  • 拷贝对象意味着什么
  • 拷贝构造和赋值拷贝有什么区别
  • 如何声明拷贝构造和赋值拷贝
  • 如何防止对象被拷贝
class person
{std::string name;int age;public:person(const std::string& name, int age) : name(name), age(age){}
};int main()
{person a("Bjarne Stroustrup", 60);person b(a);   // What happens here?b = a;         // And here?
}

特殊的成员函数

隐式的定义

// 1. copy constructor
person(const person& that) : name(that.name), age(that.age)
{
}// 2. copy assignment operator
person& operator=(const person& that)
{name = that.name;age = that.age;return *this;
}// 3. destructor
~person()
{
}

在这种情况下,成员复制正是我们想要的:复制姓名和年龄,因此我们得到一个独立的、独立的 person 对象。隐式定义的析构函数始终为空。在这种情况下这也很好,因为我们没有在构造函数中获取任何资源。在 person 析构函数完成后,隐式调用成员的析构函数:

资源管理

class person
{public:person(const char* the_name, int the_age){name = new char[strlen(the_name)+1];strcpy(name, the_name);age = the_age;}~person(){delete[] name;}
private:char *name;int age;}

默认情况下: 拷贝对象意味着拷贝它的成员,但是name在这里是一个指针,复制name是复制指针,而不是复制它指向的一片内存。这里会出现几个问题:

    1. a的变化可以观察到b的变化
    1. 一旦b销毁,a.name就是一个悬空指针
    1. 如果a销毁,删除悬空指针会出现意想不到的结果
  • 4.由于赋值没有考虑赋值之前name的指向,迟早会出现到处都是内存泄漏的情况

显示定义

//1. copy construct
person(const person &that)
{name = new char[strlen(that.name)+1];strcpy(name ,that.name);age = that.age;
}// 2.copy assignment to operator
person& operator=(const person&htat)
{if(this != &that){delete[] name;// This is a dangerous point in the flow of execution!// We have temporarily invalidated the class invariants,// and the next statement might throw an exception,// leaving the object in an invalid state :(name = new char[strlen(that.name) + 1];strcpy(name, that.name);age = that.age;}return *this;
}

异常安全

不幸的是,如果 new char[…] 由于内存耗尽而引发异常,则此解决方案将失败。一种可能的解决方案是引入局部变量并对语句重新排序:

// 2. copy assignment operator
person& operator=(const person& that)
{char* local_name = new char[strlen(that.name) + 1];// If the above statement throws,// the object is still in the same state as before.// None of the following statements will throw an exception :)strcpy(local_name, that.name);delete[] name;name = local_name;age = that.age;return *this;
}

不可复制资源

有些资源不能或不应该被复制,例如文件句柄或互斥锁。在这种情况下,只需将复制构造函数和复制赋值运算符声明为私有,而不给出定义:

private:person(const person& that);person& operator=(const person& that);

或者,您可以继承 boost::noncopyable 或将它们声明为已删除(在 C++11 及更高版本中)

person(const person& that) = delete;
person& operator=(const person& that) = delete;

rule of three

有时您需要实现一个管理资源的类(或者带有指针的类,可能意味着就需要管理资源)。 (永远不要在一个类中管理多个资源,这只会带来痛苦。)在这种情况下,请记住三条规则:

  • 显示声明 :析构函数
  • 显示声明 :拷贝构造函数
  • 显示声明 :复制赋值运算符

rule of five

从 C++11 开始,对象有 2 个额外的特殊成员函数:移动构造函数和移动赋值。

class person
{std::string name;int age;public:person(const std::string& name, int age);        // Ctorperson(const person &) = default;                // 1/5: Copy Ctorperson(person &&) noexcept = default;            // 4/5: Move Ctorperson& operator=(const person &) = default;     // 2/5: Copy Assignmentperson& operator=(person &&) noexcept = default; // 5/5: Move Assignment~person() noexcept = default;                    // 3/5: Dtor
};

参考

What is the Rule of Three

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20092.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P2P网络NAT穿透原理(打洞方案)

1.关于NAT NAT技术(Network Address Translation,网络地址转换)是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术,它使得一定范围内的多台主机只…

python算法指南程序员经典,python算法教程pdf百度云

大家好,小编来为大家解答以下问题,你也能看懂的python算法书 pdf,python算法教程这本书怎么样,现在让我们一起来看看吧! 给大家带来的一篇关于算法相关的电子书资源,介绍了关于算法、详解、算法基础方面的内…

Kaggle狗图像分类实战

文章目录 Kaggle狗图像分类实战d2l安装问题python语法学习os.path.joind2l 数据加载streamlit Kaggle狗图像分类实战 d2l安装问题 d2l安装失败,报错如上图 去下面的网站下载到该项目文件目录下再pip install即可 Python d2l项目安装包(第三方库)下载详情页面 - …

ATFX汇评:英央行利率决议来袭,大概率加息25基点

ATFX汇评:今日19:00,英国央行公布利率决议、会议纪要和货币政策报告;半小时后,英国央行行长贝利召开货币政策新闻发布会。当前英国央行基准利率5%,市场预期将加息25基点至5.25%,假若符合预期,则…

【css】背景图片附着

属性&#xff1a;background-attachment 属性指定背景图像是应该滚动还是固定的&#xff08;不会随页面的其余部分一起滚动&#xff09;。 background-attachment: fixed&#xff1a;为固定&#xff1b; background-attachment: scroll为滚动 代码&#xff1a; <!DOCTYPE h…

opencv的Mask操作,选择图片中感兴趣的区域

最近做目标检测任务的时候&#xff0c;需要对固定区域的内容进行检测&#xff0c;要用到opencv的mask操作&#xff0c;选择图片固定的区域 代码 import cv2 import numpy as npimg cv2.imread(data/images/smoking.png)# 弹出一个框 让你选择ROI | x,y是左上角的坐标 x,y,w,…

el-date-picker回显问题解决记录

el-date-picker回显问题记录 组件结构 <el-date-pickerv-model"time"type"datetimerange"range-separator"至"start-placeholder"开始日期"end-placeholder"结束日期"value-format"yyyy-MM-dd HH:mm:ss":defau…

23款奔驰C260 L更换内饰最全发光套件,提升车内氛围感

原厂1:1设计&#xff0c;免编程匹配&#xff0c;无损安装&#xff0c;可升级项目&#xff1a; 1、碳纤维中控氛围灯&#xff08;阿凡达水滴款&#xff09; 2、发光前风口&#xff1b; 3、发光后风口&#xff1b; 4、发光座椅背气氛灯&#xff1b; 5、中音发光盖板 6、主动…

数学分析:流形的线性代数回顾

因为是线性的&#xff0c;所以可以把所有的系数都提取出去。这也是多重线性代数的性质。可以看成基本的各项自变量的乘法。 这里可以看到两个不同基向量下&#xff0c;他们的坐标转化关系。 引出了张量积&#xff0c;也就是前面提到的内容。 对偶空间的例子总是比较美好。 因为…

使用express搭建后端服务

目录 1 创建工程目录2 初始化3 安装express依赖4 启动服务5 访问服务总结 上一篇我们利用TDesign搭建了前端服务&#xff0c;现在的开发讲究一个前后端分离&#xff0c;后端的话需要单独搭建服务。后端服务的技术栈还挺多&#xff0c;有java、php、python、nodejs等。在众多的技…

代理模式(Proxy)

代理模式是一种结构型设计模式&#xff0c;让开发者能够提供对象的替代品或其占位符。代理对象控制着对于原对象的访问&#xff0c;并允许在将请求提交给原对象前后进行一些处理。代理模式为原对象提供一种代理以控制对这个对象的访问&#xff0c;并由代理对象控制对原对象的引…

如何将公司服务器云映射出去

如何将公司服务器云映射出去&#xff0c;让员工在家能访问内网 要实现将公司内部服务器映射到云上&#xff0c;以使员工能够在家访问内网&#xff0c;可以考虑以下方案&#xff1a; 1.虚拟专用网络&#xff08;VPN&#xff09;&#xff1a;配置一个VPN服务器&#xff0c;在公…

podman在FreeIPA环境的支持

podman在FreeIPA环境的支持 根据实验&#xff0c; CentOS 7.9 yum仓库自带的FreeIPA Server 4.6.8&#xff0c; ipa client版本备注CentOS 7.9 yum仓库自带的FreeIPA Client 4.6.8不支持subids&#xff0c;不能跑podman。 RHEL 9.2 yum仓库自带的FreeIPA Server 4.10.1&…

青蛙过河 [递推法]

青蛙过河 [递推法] 题目描述输入输出样例输入样例输出样例 递推解答A C 代码 题目描述 有一条河&#xff0c;左边一个石墩( A A A区)上有编号为 1 &#xff0c; 2 &#xff0c; 3 &#xff0c; 4 &#xff0c; … &#xff0c; n 1&#xff0c;2&#xff0c;3&#xff0c;4&am…

0101sub-process /usr/bin/dpkg returned an error code-dpkg-linux问题集

kali linux有段时间没用了&#xff0c;现在有点时间想着继续学习下网络安全&#xff0c;那就升级更新下。 apt-get update && apt-get upgrade等待一段时间后&#xff0c;下载完毕执行安装和更新&#xff0c;更新的过程中报错退出了 问题1 更新kali-themes 需要kali-t…

电脑更新win10黑屏解决方法

电脑更新win10黑屏解决方法 电脑黑屏出现原因解决步骤 彻底解决 电脑黑屏 出现原因 系统未更新成功就关机&#xff0c;导致系统出故障无法关机 解决步骤 首先长安电源键10s关机 按电源键开机&#xff0c;出现logo时按F8进入安全模式。 进入自动修复环境后&#xff0c;单击…

[nlp] TF-IDF算法介绍

&#xff08;1&#xff09;TF是词频(Term Frequency) 词频是文档中词出现的概率。 &#xff08;2&#xff09; IDF是逆向文件频率(Inverse Document Frequency) 包含词条的文档越少&#xff0c;IDF越大。

宋浩概率论笔记(二)随机变量

本章节内容较多&#xff0c;是概率论与数理统计中最为重要的章节&#xff0c;对于概率密度和分布函数的理解与计算要牢牢掌握&#xff0c;才能在后期的学习中更得心应手。

mybatis log插件

目前idea当中已经实施收费了 最近找了一个不收费的插件安装上重启一下就行了 点我下载提取码&#xff1a;sjc8

Docker build 命令详解

build 命令用于使用 Dockerfile 创建镜像。 语法&#xff1a; $ docker build [OPTIONS] PATH | URL | -OPTIONS 说明 # 可通过帮助命令查看 $ docker build --help--build-arg[]: 设置镜像创建时的变量--cpu-shares: 设置 cpu 使用权重--cpu-period: 限制 CPU、CFS 周期--cpu…