条款5:默认函数
必须定义自己的函数的特殊情况
1、如果在含有引用成员的类内使用赋值操作,必须自己定义赋值操作符。因为C++不支持对引用对象映射的更改。
2、含有const成员的类也是这样。
3、基类将赋值运算符声明为private时,编译器拒绝为派生类生成赋值运算符。因为编译器为派生类生成的赋值运算符是可以处理基类部分的,但是派生类无权调用基类的private成员,因此,编译器拒绝为派生类生成赋值运算符。
条款6:如不想使用编译器自动生成的默认函数,就应该明确拒绝
1、将自己定义的构造/赋值运算声明为private的,一方面覆盖了编译器的默认函数,另一方面,也组织用户使用这些函数。 2、进一步的,为了阻止成员函数或者友元函数调用private复制构造函数或赋值运算符,定义一个基类,在基类中定义这些私有的赋值/复制函数,这样因为条款12,派生类的有缘无权调用基类额私有成员。条款7:为多态基类声明virtual析构函数
1、如果基类的析构函数不是虚的,在释放空间时会造成局部释放,即只释放了基类部分,派生类部分没有释放,导致内存泄漏; 2、任何函数一般只要有虚函数,就应该有虚析构函数; 3、对于一个不作为基类的类,将他的析构函数设置为virtual的是不好的。每一个带有virtual函数的类都有一个虚表(vtbl),这个虚表是由函数指针构成的数组。当对象调用一个virtual函数时,编译器查找虚表选择适当的函数指针。将一个非基类的析构函数声明为虚的,会导致存储的增多,也丧失其他语言的移植性。 4、所有的STL容器都不带virtual析构函数,因此自定义继承自他们的类,当操作指针时,提防出现内存泄漏问题。C++中不要继承标准容器。 5、想把一个类定义为抽象类,但是找不到一个合适的成员函数把他设置为纯虚函数,可以把析构函数设置为纯虚函数。 只有在有多态需求的基类中定义虚析构函数,条款6.2中的基类设置并不是为了实现多态,不需要设置虚析构函数。条款8:别让异常逃离析构函数
to be continue条款9:不在构造和虚构过程中调用virtual函数
当调用派生类构造函数时,首先调用基类的构造函数,在基类中,如果有虚函数,那么此时的类型是基类,调用的虚函数版本是基类的函数。条款10:赋值运算符返回*this引用
为了实现连锁操作,赋值运算符返回调用者本身。另外和赋值相关的运算符重载也尽量遵循这个规则:+=,-=。条款11:赋值运算符重载中处理自我赋值
如:w=w;指针和数组操作的赋值不容易发现他是自我赋值。在赋值运算符重载函数中出现自我赋值是不安全的:Wifgt::operator=(const Wifgt & rhs){delete pb;//删除原来的动态内存pb=new Wifgt(rhs);//赋给指针新的动态内存(传入的引用),但是当引用参数和=运算符的调用者是一个(指向同一个动态内存),那么前面已经删除了这个动态内存,rhs的动态内存也删除了,这句话将指针指向一个已经删除的对象!!!return *this;}同时,也要考虑异常安全性的问题:在调用new分配新内存时,如果内存不足或者拷贝构造函数抛出异常,第二句最终也会指向一个被删除的对象解决办法:(1)先分配新内容,在释放已有的内容;这样只有在分配新内容成功之后,才去释放原来的内容。(2)使用copy anf swap技术条款12:复制对象时勿忘其每一个成分
1、两个copy函数应该确保拷贝所有的成员和基类的成员(在初始化列表中使用合适的基类构造函数)2、赋值运算符和拷贝构造函数不要互相调用。如果两者出现很多重复的代码,应该使用第三个函数包含共同机制。