【Effective C++】第二章 构造/析构/赋值运算

第二章 构造/析构/赋值运算

1、编译器可以暗自为class创建default构造函数、copy构造函数、copy assiginment操作符,以及析构函数。

2、为驳回编译器自动提供的机能,例如copy构造函数和copy assiginment操作符,可将相应的成员函数声明为private并且不予实现。 

 3、当derived class对象经过由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义——实际执行时通常发生的是对象的derived成分没有被销毁。消除这个问题的做法是:给base class一个virtual析构函数。

 任何class只要带有virtual函数都几乎确认应该也有一个virtual析构函数。

       当class不企图被当作base class,令其析构函数为virtual往往是个馊主意。因为如果class内含有virtual函数,其对象的体积会增加。

总结: 带多态性质的base classes应该声明一个virtual析构函数。当不做base classes使用,或不是为了具备多态性,就不应该声明virtual析构函数。

4、当析构函数吐出异常,程序可能过早结束或出现不明确行为。当析构函数必须执行一个动作,而这个动作可能会抛出异常,当析构函数抛出异常,也就是允许它离开这个析构函数,那会造成问题,因为那就是抛出了难以驾驭的麻烦。

解决办法:通过调用abort完成。调用abort可以抢先制“不明确行为”于死地。但将异常吞掉,压制了“某些动作失败”的重要信息。另一个办法,class应该提供一个普通函数执行该操作。

总结:

  • 析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或结束程序。
  • 如果客户端对某个操作函数运行期间抛出异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。 

5、不要在构造函数和析构函数中调用virtual函数,因为vptr指针是分步完成的,在基类的构造函数中调用virtual函数,并不会发生多态,而是直接调用了基类的virtual函数版本。

6、在重载operator=运算符时,需返回一个引用,原因是为了形成连锁等于的形式,因为返回引用可以当左值。 

7、在operator=中处理“自我赋值”,在赋值操作时,我们都会先删除旧对象,在根据新的对象值创建一个新对象返回,但如果新对象和旧对象一样,即指向同一个空间,则在最初删除旧对象时,已经把新对象的值已删除,所以会出现问题,应该在最初判断下两者是否相等,当相等时直接返回自身。

8、复制对象时勿忘其每一个成分。当存在继承时:(1)复制所有local成员变量,(2)调用所有base classes内适当的copying函数。当copy构造函数和copy assignment操作符有相近代码时,不要尝试以某个copying函数实现另一个copying函数,而是建立一个新的成员函数给两者调用,这样的函数往往是private而且常被命名为init。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烊萌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值