Effective C++ 02

Rule five

了解C++默默编写并调用那些函数 (Know waht functions C++ silently writes andcalls)

 

对于一个Empty Class ,C++编译器会为他声明:

1.一个copy构造

实现简单的non static 对象拷贝

2.一个copy assignment操作符

实现简单的non static 对象拷贝

3.一个析构函数‘

编译器产生的析构是non virtual 的, 除非base class 本身的声明有virtual的析构函数。

4.一个default构造函数

如果存在构造函数,则不会创造。

注意:

只有在这些函数被调用时才被编译器创造出来。

copy构造和copy assignment操作符 只有在生成的代码合法并且有适当机会证明其有意义才会有效, 否则编译器会将拒绝为其生成代码

 

注意 :

编辑器可以安子为class'创建以上函数,但是不是一定会创建。

 

Rule six

若不想使用编译器自动生成的函数,就该明确的拒绝 (Explicitly disallow the use ofcompiler-generated functions you do not want)

 

原因:组织默认的copy方法

方法:

1.声明private的copy构造和copy assignment操作符 ,但是不定义。

2.使用uncopyable这样的baseclass也是一种方法

class uncopyable

{

private:

uncopyable(const uncopyable&);

uncopyable& operator = (constuncopyable&);

}

 

class A :private uncopyable

{}

但是这种方法容易导致的一种继承

 

总结:

为驳回编译器自动提供的功能,可将相应的成员函数生命为private并且不予实现

 

Rule seven

为多态基类声明virtual析构函数(Explicitly disallow the use ofcompiler-generated functions you do not want)

 

原因:

当一个派生类对象经由一个基类对象指针删除, 且该基类存在一个 non virtual 的析构,那么结果是未定义-------通常发生的是派生类的成分没有被析构。

 

解决方案:

给基类定义一个virtual 的析构函数

 

如果class 内没有一个virtual 则不需要对其析构进行virtual。

注意:对于STL 请不要继承!!!

 

总结:

1.带多态性质的base class应该声明哟个virtual析构函数。如果class带有任何的virtual函数, 他就用该拥有一个virtual析构函数。

2.class 的设计目的如果不是为base class使用,或者不是为了多态使用就不应该声明virtual的析构函数。

Rule eight

别让异常逃离析构函数 (Prevent exception from leaving destructors)

 

C++不禁止析构函数吐出异常,但是不鼓励。

如果在析构函数中出现异常,会导致不可知的问题

 

解决方案:

1.使用try catch 通过调用abort终止函数。

2.使用try catch 将异常抛出

注意:两者都不能对导致close抛出异常的情况作出反应。

 

最佳的解决方案:

将析构内内容非装成一个函数,在析构内调用。将风险从析构函数转移到客户函数内。

 

总结:

1.析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉异常,然后吞下或者结束程序。

2.如果客户需要对摸个操作函数运行期间抛出的异常作出反应,应该提供一个普通接口而非析构函数执行该操作。

Rule nine

绝不在构造和析构内调用virtual函数 (Never call virtual functions duringconstruction or destruction)

 

在base class 的构造期间 ,virtual函数并不是virtual函数。

 

总结:

在构造和析构期间不要调用virtual函数,因为这些调用从不下降至派生类。

Rule ten

令operator= 返回一个reference to *this(Have assignment operators return a reference to*this)

 

这只是个协议,如果不遵循也是可以运行的。

Rule eleven

在operator= 内处理自我赋值(Handle assignment to self in operator=)

 

自我赋值,即w=w ,是可能存在的, 是合法的。

 

如果存在operator=对象的目标和起源是一个值,那么对于起源的销毁可能会导致目标的销毁。

解决方案:

1.在operator= 最前面添加一个证同测试。if() return;

2. swap-and-copy技术(?)

 

总结:

1.确保当对象自我赋值时operator=有良好的行为。其中技术包括比较来源与目标的地址、精心周到的语句顺序、copy-and-swap

2.确保任何函数如果操作一个以上的对象,而且多个对象是一个对象时,其行为是正确的。

 

Rule twelve

复制对象时勿忘其每一个成分(Copy all parts of an object)

 

编写copying函数时确保:

1.复制所有local成员变量

2.调用所有base classes copying函数

 

为避免copy构造函数和copy assignment操作符的代码重复,不可两者相互调用,正确的方法是船舰一个init成员函数供两个函数使用。

 

总结:

1.Copying函数应当确保赋值对象内的所有成员变量以及所有base classes成分。

2.不要尝试以某个copy函数实现另一个copy函数,应当建立一个第三方函数共同调用。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值