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函数,应当建立一个第三方函数共同调用。