Effective C++读书笔记2(构造/析构/赋值运算)

《Effective C++》 读书笔记(详细总结55条款)上篇 下面从四个方面来说 (1) C++ 以 C 为基础,很多语句语法都没有改变,只是进行了扩展,C++ 解决问题的时候,可以理解为 C 的高效解法 (2) 面向对象,有构造函数,析构函数,继承、封装、多态、虚函数动态绑定,这是不同于C 语言的部分 (3) 泛型编程、可以理解为代码的模型,但是代码本身并不占用内存空间,只有在实例化的时候,才分配内存,所以可以提高代码复用性 阅读详情

◆条款05: 了解C++默默编写并调用哪些函数

一个像这样的空类:

  1. class Empty {
  2. };

C++编译器就会声明一个拷贝构造函数、一个拷贝赋值函数和一个析构函数,如果你没有声明任何构造函数,编译器也会自动添加一个默认构造函数,如下:

  1. class Empty {
  2. public:
  3.     Empty() { ... }                             // 默认构造函数
  4.     
  5.     Empty(const Empty& rhs) { ... }             // 拷贝构造函数
  6.     ~Empty() { ... }                            // 析构函数
  7.     Empty& operator=(const Empty& rhs) { ... }  // 拷贝赋值函数
  8. };

注: 如果该类含有一个引用类型的成员变量或const类型的成员变量,编译器无法生成拷贝赋值函数,还有一种情况就是如果基类的拷贝赋值函数为private,编译器也无法为派生类生成拷贝赋值函数。

 

◆条款06: 若不想使用编译器自动生成的函数,就该明确拒绝

如果我不想类之间的对象能互相拷贝,有两种方法:

  1. class Test {
  2. public:
  3.     ...
  4. private:
  5.     Test(const Test&);           // 只有声明没有定义
  6.     Test& operator=(const Test&);
  7. };

这个方法可以归结为一句话: 将成员函数声明为private而且故意不实现它们。成员函数和友元函数不慎调用的时候,也会因为没有实现而报链接错误。

这种方法可能不是很完美,因为有时会将错误推迟到链接阶段,还有一种方法:

  1. class Uncopyable { 
  2. protected: 
  3.     // 允许派生对象构造和析构 
  4.     Uncopyable()  { } 
  5.     ~Uncopyable() { }
  6. private:
  7.     // 阻止拷贝
  8.     Uncopyable(const Uncopyable&);
  9.     Uncopyable& operator=(const Uncopyable&);
  10. };
  11. class Test: private Uncopyable {
  12.    ...
  13. };

Boost库中有一个类似的类可以提供这样的功能: noncopyable

 

◆条款07: 为多态基类声明virtual析构函数

为那些预备作多态用的基类声明virtual析构函数,如果不这样的话,派生类析构的时候只调用基类的析构函数,而不会调用派生类自己的析构函数。如果一个类有任何virtual函数,就应该有一个virutal析构函数。

注: 当且仅当是基类且是为了多态用时才必须遵守。

 

◆条款08: 别让异常逃离析构函数

析构函数不能抛出异常,因为无法确定会让异常抛到哪一层,尽量封装这些能抛出异常的代码成一个用户手工调用的成员函数,在析构函数里只做最后一层保险,截获该异常。

 

◆条款09: 绝不在构造和析构过程中调用virtual函数

构造和析构时调用的virtual函数只是基类的函数,不是派生类的函数。

 

◆条款10: 令operator=返回一个reference to *this

任何赋值成员函数必须返回*this,如:

  1. class Widget {
  2. public:
  3.     
  4.     ...
  5.   
  6.     Widget& operator=(const Widget& rhs) {
  7.         ...
  8.         return *this;
  9.     }
  10.     ...
  11. };

◆条款11: 在operator=中处理“自我赋值”

赋值时并不确定赋值的两方是不是同一对象,如果无视这个而直接进行下一步的赋值工作,很可能会由于使用刚刚被删除的内存而引起访问一个已被删除的对象的问题,所以一般要进行一个比较是否是同一对象的步骤再接着处理。如:

  1. class Bitmap { ... };
  2. class Widget {
  3.     ...
  4. private:
  5.     Bitmap* pb;
  6. };
  7. Widget& Widget::operator=(const Widget& rhs)
  8. {
  9.     // 如果没这一步的话很可能出现rhs被删除后又调用rhs.pb的情况
  10.     if(this == &rhs) return *this;
  11.     delete pb;
  12.     pb = new Bitmap(*rhs.pb);
  13.     return *this;
  14. }

也可以不比较而通过保存旧对象最后成功处理后再删除的方法,可能效率要稍微低一点,因为做了无用的操作。

  1. Widget& Widget::operator=(const Widget& rhs)
  2. {
  3.     Bitmap* pOrig = pb;
  4.     pb = new Bitmap(*rhs.pb);
  5.     delete pOrig;
  6.     return *this;
  7. }

不过可以再添加一个比较的分支来处理自我赋值,就是这样写好像有点太难看了。

 

◆条款12: 复制对象时勿忘其每一个成分

如果你要实现自己的拷贝构造函数和拷贝赋值函数,那你就必须确保你的对象里的每一个成员变量都要被复制,包括基类的成员变量。

安时积分法和开路电压法结合估算锂电池SOC 基于安时积分法和开路电压法结合的锂电池SOC估计Simulink仿真建模,利用安时积分法计算放电过程中的SOC,在搁置状态利用开路电压法进行SOC修正。 阅读详情

相关推荐

(UE4 4.27) HISM性能优化:从空间剔除到合批渲染的实战解析

本文深入解析了UE4 4.27中HISM(UHierarchicalInstancedStaticMesh)组件的性能优化原理与实战技巧。核心在于利用其N叉树空间结构实现高效的CPU视锥剔除,并结合GPU实例化进行合批渲染。文章详细探讨了从控制叶子节点粒度、平衡剔除精度与渲染效率,到结合LOD系统等关键参数的调优方法,为开放世界或大场景的植被性能瓶颈提供了系统解决方案。

weixin_29015051的博客 328

《Effective C++》读书笔记 2.构造/析构/赋值运算

构造/析构/赋值运算 条款05:了解C++默默编写并调用哪些函数 编译器自动生成copy构造函数、copy assignment操作符、default构造函数(没有声明任何构造函数的时候) 这些函数都是public且inline的 注意,只有在这些函数被需要(被调用)的时候它们才会被编译器创造出来 关于copy构造函数和copy assignment操作符=,只有当生出的代码合法且有适当机会证明它有意义,编译器才会自动生出。比如成员变量里面有引用或者const,无法赋值,编译器没法解决,就不生成 条款06:

Estrike的博客 215

abaqus2matlab的安装与使用:如何用matlab提取abaqus的odb结果

官网abaqus2matlab官网地址matlab社区地址matlab社区地址在这里可以看到.m文件的源码论文:Abaqus2Matlab: A suitable tool for finite element post-processingabaqus2matlab可以处理.inp、.fil、.odb三种类型的文件。.inp文件:处理功能就在于只是单纯的输出inp文件,由于我自己写了自己的函数,不需要用到这个功能。

qianxin1234的博客 2019

【读书笔记】Effective C++-2 构造/析构/赋值运算(之一)

Effective C++读书笔记 --By Nathan.Yu 2007-11-13-- 2 构造/析构/赋值运算(之一) 条款05:了解C++默默编写并调用哪些函数 如果你自己没声明,编译器就会为类声明一个copy构造函数、一个copy assignment操作符和一个析构函数。此外如果你没声明任何构造函数,编译器也会为你声明一个default构造函数。只有当这些函数被需要(被调用

@塘外人 704

先进封装基础知识

想象一下,芯片就像是电脑或手机的大脑,但它非常脆弱,需要被保护起来。芯片封装就是给芯片穿上一件“保护衣”,这件“保护衣”不仅可以保护芯片,还能帮助芯片与外部世界进行沟通。

阿拉伯梳子的专栏 1145

从零开始:用这些公开数据集搞定电力AI项目(含鸟巢、绝缘子、负荷预测等33个实战资源)

本文系统梳理了电力AI领域33个精选公开数据集,涵盖目标检测、负荷预测等关键场景,如鸟巢检测、绝缘子缺陷识别等。通过实战案例解析数据预处理、模型选型及性能优化策略,帮助工程师快速构建端到端解决方案,解决电力AI项目中的数据获取与处理难题。

weixin_42522552的博客 218

【读书笔记】Effective C++-2 构造/析构/赋值运算(之四)

Effective C++读书笔记 --By Nathan.Yu 2007-11-24-- 2 构造/析构/赋值运算(之四) 条款08:别让异常逃离析构函数 C++并不禁止析构函数吐出异常,但它不鼓励你这样做! 理由:        设:std::vector v; 假设v中有多个Widget,在销毁v的过程中,当有2个以上的Widget在销毁的时候抛出异常,对C++而言就太多了。在

@塘外人 884

合泰单片机HT32之keil5开发环境搭建(一)

1. 前言 这两天在准备合泰杯,但是总是感觉无从下手,因为合泰单片机的资料教程什么的非常少,不像stm32那样。而且听说要用合泰单片机的专用IDE,感觉当场被劝退了。后来经过查找资料,发现合泰单片机也有keil5的支持包,也就是说可以从库函数进行开发,不用从寄存器进行开发,但我找了好久,并没有找到教程,后来实在没办法,打算自己动手搭建环境,经过了大概两天的挣扎后,终于成功地搭建好了环境,也成功地点...

weixin_44713763的博客 8671

【读书笔记】Effective C++-2 构造/析构/赋值运算(之二)

Effective C++读书笔记 --By Nathan.Yu 2007-11-14-- 2 构造/析构/赋值运算(之二) 条款06:若不想使用编译器自动生成的函数,就该明确拒绝 【要点摘录】所有编译器生成的函数都是public且inline的。   如何阻止拷贝行为? 将copy构造函数和copy assignment操作符声明为private,并不去定义(实现)它们。借由明

@塘外人 712

TGAT Python:图神经网络中的动态图算法

其中,图神经网络中的动态图算法成为了研究的热点之一。在模型的 forward 方法中,通过循环调用 TGATLayer 实例来进行图神经网络的前向传播。最终,模型返回图中节点的表示向量 output,可以用于图分类等任务。TGAT 算法的核心思想是在节点之间建立注意力连接,以捕捉节点在不同时间步之间的关系。TGAT 算法通过引入注意力机制和时间信息,从而有效地对动态图数据进行建模和分析。通过以上 Python 代码,我们可以方便地构建和训练 TGAT 模型,并在图分类任务中应用它。

2301_79366435的博客 1830

MathType公式使用技巧汇总——Mathtype怎么在word中编辑公式?论文中公式有哪技巧?有哪些注意事项?论文中的公式怎么写?

如果word中到公式编号(2-1)中间的符号如下图........ .......类似与省略号的,这是手动打的空格,公式和编号的位置都是手动敲空格操作的,这种就只是使用MathType写了公式而已,格式上还是很不方便的。**如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。而第二种,是公式里面带的括号符号,他是可以随着公式结构自适应变化的。这时需要将公式插入到一行文字的某处,

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 5万+

《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记

章节回顾: 《Effective C++》第1章 让自己习惯C++-读书笔记 《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记 《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记 《Effective C++》第3章 资源管理(1)-读书笔记 《Effective C++》第3章 资源管理(2)-读书笔记 《Effective C++》...

weixin_33912453的博客 118

设计四翼无人机(Quadcopter)的自主降落控制算法

为四翼无人机建立动力学模型,包括其姿态(Pitch, Roll, Yaw)和位置(X, Y, Z)的变化。可以使用Aerospace Blockset中的预制模块,或者根据具体需求构建自定义模型。示例:简化动力学模型利用块模拟四翼无人机的基本行为,确保模型能够反映电机输出如何影响姿态和位置变化。

amy_mhd的博客 243

【effective c++读书笔记】【第2章】构造/析构/赋值运算(1)

条款05:了解C++默默编写并调用哪些函数 1、如果你自己没声明,编译器就会为类声明(编译器版本的)一个拷贝构造函数,一个拷贝赋值操作符和一个析构函数。此外如果你没有声明任何构造函数,编译器也会成为你声明一个默认构造函数。所有这些函数都是public且inline。惟有当这些函数被需要(被调用),它们才会被编译器创建出来。即有需求,编译器才会创建它们。 例如: class Empty{};

ruan875417的专栏 446

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【effective c++读书笔记】【第2章】构造/析构/赋值运算(2)

条款09:绝不在构造和析构过程中调用virtual函数 例子: #include<iostream> #include<string> using namespace std; class Base{ public: Base(){ test(); } virtual void test(){ cout << "Base test" &lt...

weixin_30832405的博客 88

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【读书笔记】Effective C++-2 构造/析构/赋值运算(之三)

Effective C++读书笔记 --By Nathan.Yu 2007-11-15-- 2 构造/析构/赋值运算(之三) 条款07:为多态基类声明virtual析构函数 问题:何时该声明virtual析构函数,何时不该这样做? 【要点摘录】C++明确指出,当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtu

@塘外人 826

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记

《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记 章节回顾: 《Effective C++》第1章 让自己习惯C++-读书笔记 《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记 《Effective C++》第8章 定制new和delete-读书笔记   条款05:了解C++默默编写

zdy0_2004的专栏 428

Effective C++读书笔记之构造/析构/赋值运算

本文主要概括一下Effective C++一书中的构造/析构/赋值运算章节的内容,并且做简要的应用分析。

张小酒的博客 497

Effective C++ | 读书笔记 (一)

这意味着,如果你在一个编译单元中依赖于另一个编译单元中的全局静态对象的初始化结果,你的程序可能会遇到未定义行为,因为那些对象的初始化次序是不确定的。在构造、析构函数中一定只会调用本类中的虚函数。原因:当基类指针(引用)指向子类对象时,如果析构对象通过delete 指针的方式,只会调用基类的析构函数,不会调用子类的析构函数。如果把这个当做是基类,会有问题,析构函数只有声明没有定义,析构函数从派生类到基类的调用时,会发生链接错误。时,先调用基类的构造函数,此时派生类还没有被构造出来,所以调用的是基类的虚函数。

m0_74795952的博客 1042
上一篇: Effective C++读书笔记1(让自己习惯C++)
下一篇: 如何实现一个支持共享内存的Map或Set
mentalmap
博客等级 码龄22年 0粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值