Effective C++ -- 构造析构赋值运算
05.了解C++默默编写并调用哪些函数
- 编译产生的析构函数时non-virtual,除非这个类的基类析构函数为virtual
- 成员变量中有引用和const成员时,无法自己主动生成copy assignment函数
- 基类将copy assignment操作符声明为private时。编译器拒绝为其derived classes生成一个copy assignment操作符。
06.若不想使用编译器自己主动生成的函数,就该明白拒绝
- 将自己主动生成的默认构造函数,拷贝构造函数,copy assignment声明为private
- 声明为private并不绝对安全。成员函数和友元函数能够进行调用 -- 进行声明,但不定义(产生链接错误)
- 定义一个基类。将默认构造函数,拷贝构造函数。copy assignment声明为private。由派生类继承该基类(产生编译错误。boost中的noncopyable类)
07.为多态基类声明virtual析构函数
- 基类指针指向派生类时,delete基类指针,无法调用到派生类的析构函数
- 不论什么class仅仅要带有virtual函数,应该有一个virtual析构函数。
- 当class不含virtual函数,通常表示它并不意图被用作一个base class。
- 当class不企图被当做base class。其析构函数为virtual往往是个馊主意。(占用空间,减少效率)
08.别让异常逃离析构函数
- 析构函数未捕获异常时,假设该类对象存储于容器中。产生异常后可能导致容器中的其它对象无法析构。
- 析构函数须要捕获异常,某些引发异常的操作可移出析构,由客户调用进行处理
09.绝不在构造和析构中调用virtual函数
- base class构造期间。virtual函数绝不会下降到derived class阶层。构造期间。virtual函数不是virtual函数。
- 当base class构造函数运行时derived class成员变量尚未初始化,假设下降到derived class,derived class将会使用为初始化的local成员变量。
- derived class对象的base class构造期间。对象的类型时base class。
- 一旦derived class析构函数開始运行,进入base class析构函数后,对象类型被视为base class。
10.令operator=返回一个reference to *this
为了实现连锁赋值,赋值操作符必须返回一个reference指向操作符左側实參。
仅仅是协议,并不是强制。
Widget& operator=(const Widget& rhs) {return *this;}
问题:
能否够返回常量引用?
11.在operator= 中处理自我赋值
- 须要解决自我赋值安全性和异常安全性
class Bitmap {...};
class Widget {
private:
Bitmap* pb;
}; Widget& Widget::operator=(const Widget& rhs)
{
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
};
- 以上代码问题:当自我赋值时,将删除自身的pb。构造新bp时。使用一个已删除的对象。
解决方法例如以下:
Widget& Widget::operator=(const Widget& rhs)
{
if (this == &rhs)
return *this;
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
- 以上代码存在问题:new Bitmap导致异常时,pb指向一个已删除的区域。解决方法例如以下:
Widget& Widget::operator=(const Widget& rhs)
{
if (this == &rhs)
return *this; Bitmap* pOrig = pb;
pb = new Bitmap(*rhs.pb);
delete pOrig;
return *this;
}
12.复制对象时勿忘其每个成分
- 新加入成员变量时须要改动复制构造函数,copy assignment函数。
class PriorityCustomer: public Customer {
public:
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
private:
int priority;
}; PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs):priority(rhs.priority)
{
log("");
} PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
log("");
priority = rhs.priority;
return *this;
}
- 以上代码问题:未调用基类的拷贝构造函数,未调用基类的赋值操作符重载函数。正确代码例如以下:
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs):Customer(rhs),priority(rhs.priority)
{
log("");
} PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
log("");
Customer::operator(rhs);
priority = rhs.priority;
return *this;
}
- 无法在拷贝构造函数中调用基类的赋值操作符重载。无法在赋值操作符重载函数中调用基类的拷贝构造函数。
Effective C++ -- 构造析构赋值运算的更多相关文章
- Effective C++ —— 构造/析构/赋值运算(二)
条款05 : 了解C++默默编写并调用哪些函数 编译器可以暗自为class创建default构造函数.copy构造函数.copy assignment操作符,以及析构函数. 1. default构造函 ...
- 《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- 《Effective C++》第2章 构造/析构/赋值运算(1)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- EffectiveC++ 第2章 构造/析构/赋值运算
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter 2 构造 / 析构 / 赋值 条款 05:了解C++ ...
- Effective C++ 笔记二 构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inlin ...
- Effective C++笔记:构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- Effective C++笔记(二):构造/析构/赋值运算
参考:http://www.cnblogs.com/ronny/p/3740926.html 条款05:了解C++默默编写并调用哪些函数 如果自定义一个空类的话,会自动生成默认构造函数.拷贝构造函数. ...
- 【Effective C++】构造/析构/赋值运算
条款05:了解C++默默编写并调用哪些函数 默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数构成了一个类的脊梁,只有良好的处理这些函数的定义才能保证类的设计良好性. 当我们没有人为的定义上面的几个函 ...
- Effective C++ 2.构造 析构 赋值运算
//条款07:为多态基类声明virtual析构函数 // 1.若基类的析构函数不定义为虚函数,由于基类的指针或引用可以指向派生类的对象,则在删除基类对象的时候可能会出错,导致破坏数据结构. // 2. ...
随机推荐
- HDU2795 Billboard 【线段树】+【单点更新】
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 14.1.3 Turning Off InnoDB 关掉InnoDB
14.1.3 Turning Off InnoDB 关掉InnoDB: Oracle 推荐InnoDB 作为首选的存储引擎用于典型的数据库应用,从单用户的wikis到博客, 到高端应用把性能推到极限. ...
- 基于visual Studio2013解决面试题之0403串联字符串
题目
- v$lock 视图访问慢解决方法
V$ 视图访问慢 --解决方法 分析:可能是有数据字典统计信息过久,造成. exec dbms_stats.gather_fixed_objects_stats; ------收集所有数据字典的fix ...
- 快速排序的时间复杂度nlogn是如何推导的??
本文以快速排序为例,推导了快排的时间复杂度nlogn是如何得来的,其它算法与其类似. 对数据Data = { x1, x2... xn }: T(n)是QuickSort(n)消耗的时间: P(n)是 ...
- javascript 自己主动绑定JS callback 的方法函数
自己写的一个javascript 智能绑定callback 而且调用运行的函数.主要用于异步请求的 ajax中: <!DOCTYPE html> <html> <head ...
- ListView+CheckBox两种解决方式及原因分析
近期在用ListView+CheckBox搞一个item选中的项目,我将CheckBox的focus设置为false,另我大喜的是,CheckBox居然能够选中(窃喜中),这么简单就搞定了,由于数据量 ...
- String[255]在高版本Delphi里还是被解释成Byte,总体长度256,使用StrPCopy可以给Array String拷贝字符串(内含许多实验测试)
学了好多不了解的知识: procedure TForm1.Button1Click(Sender: TObject); var s1 : String; s2 : String[]; begin s1 ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
- 【Android UI设计与开发】第17期:滑动菜单栏(二)开源项目SlidingMenu的示例
通过上一篇文章的讲解,相信大家对于开源项目SlidingMenu都有了一个比较初步的了解(不了解的可以参考上 一篇文章),那么从这一章开始,博主将会以SlidingMenu为重心,给大家带来非常丰富的 ...