1、尽量用const和inline而不用#define,在定义常量时用const,定义一些小函数时用inline。定义指针常量时要把指针和常量都定义为const,定义成员常量时要把成员定义为static保证所有的实例只有这一个常量。
2、尽量用<iostream>而不用<stdio.h>,尽量用new和delete而不用malloc和free,对应的new和delete要采用相同的形式,尽量使用C++风格的注释。
3、析构函数里对指针成员调用delete,指针成员再构造里如果没有分配就要指向0,delete空指针是安全的。
4、安装set_new_handler()函数,当内存分配不够时可以回自动调用这里传入的函数,可以使程序自然的退出或者想办法分配出内存。
5、每一个需要动态分配内存的类都需要有一个拷贝构造函数和一个赋值操作符
6、尽量使用初始化而不要在构造函数里赋值,因为在构造函数里复制等于成员函数被赋值了两次。
7、成员在类中声明的顺序决定了他们被初始化的顺序,找个和初始化列表中的顺序无关。
8、基类一定要有虚析构函数,因为用即被的指针去删除派生类的结果是无法知道的。
9、让让operator=返回*this的引用,很多程序员回返回void,但这样会导致无法写出a=b=c这种链式赋值,在operator=中一定要检查自己给自己赋值的情况。
10、类的设计要完整而小,避免public 接口出现数据成员。
11、尽可能使用const
12、避免对指针和数字进行重载,因为当传入参数值0时,不知道是一个空指针还是0 ,而程序肯定会认为是数字。
13、如果不想使用隐式生成的函数就要显式地禁止它,例如有时我们如果禁止赋值就需要将operator =放进private。
14、避免返回内部数据的句柄,也不要返回局部对象的引用
15、尽可能地推迟变量的定义
16、一般来说,实际编程时最初的原则是不要内联任何函数,除非函数确实很小很简单,因为一旦编译器拒绝进行内联,那么这些声明为内联的外联函数将带来反而更大的开销。
17、降低文件之间依赖度的方法:
只要有可能,尽量让头文件不要依赖于别的文件;如果不可能,就借助于类的声明,不要include它的定义,只要生明就可以。
如果可以使用对象的引用和指针,就要避免使用对象本身。定义某个类型的引用和指针只会涉及到这个类型的声明。定义此类型的对象则需要类型定义的参与。
18、public继承代表“是一个”,成员代表“有一个”。
19、决不要重新定义继承而来的非虚函数,决不要重新定义继承而来的缺省参数值。
20、私有继承的含义是指基类的所有成员都是派生的私有成员,私有继承不是继承关系,它表示通过……而实现,纯粹一种实现技术。
21、尽量使用C++风格的类型转换:static_cast(常规的类型转换), const_cast(去掉const), dynamic_cast(基类转化为子类), 和reinterpret_cast(在函数指针类型之间进行转换)。
22、避免无用缺省构造函数,如果可以没有缺省的构造函数,就不需要有。在没有缺省的构造函数而是用数组type a[10]时会有麻烦,解决方法是:
使用指针数组:type** p=new type*[10];for(int i=0;i<10;i++){type[i]=数值};
使用placement new,也就是先分配空间,再在已分配空间上构造:
void* raw=operator new[](10*sizeof(type)); type*a=static_cast<type*>(raw);
for(int i=0;i<10;i++){
new(&a[i]) type(数值)
}
析构时要用placement delete
for(int i=0;i<10;i++){
a[i].~type();
operator delete[](raw);
}
23、自增和自减的符号重载应该写成
T& operator++(); // ++ 前缀
const T operator++(int);++ 后缀
24、不要重载“&&”,“||”, 或“,”
25、不同类型的new和delete的意义:new/delete/new[]/delete[]:先扥配空间,然后在这个空间上执行构造函数构造对象
operator new(size)/operatoe delete/operator new[](size)/operator delete[];只是分配一个raw的空间,并不进行构造实体,返回的是void
new (buffer) type():在内存空间buffer上进行构造一个type实例,它的清理时需要直接显示调用type的析构函数。
26、使用auto_ptr可以避免资源的泄露,因为这里把指针装在了auto_ptr的实体里,实体没有时调用析构函数会delete掉这个指针。
27、当你必须支持某些操作而不总需要其结果时,懒惰计算是在这种时候使用的用以提高程序效率的技术。当你必须支持某些操作而其结果几乎总是被需要或被不止一次地需要时,分期摊还是在这种时候使用的用以提高程序效率的一种技术
28、用a+=b替代a=a+b
29、如果想在同一程序下混合C++与C编程,记住下面的指导原则:将在两种语言下都使用的函数申明为extern 'C',只要可能,用C++写main()。
30、具有虚拟行为的非成员函数很简单。你编写一个虚拟函数来完成工作,然后再写一个非虚拟函数,它什么也不做只是调用这个虚拟函数.
31、在类中的静态对象实际上总是被构造(和释放),即使不使用该对象。与此相反,只有第一次执行函数时,才会建立函数中的静态对象,所以如果没有调用函数,就不会建立对象。(不过你得为此付出代价,每次调用函数时都得检查是否需要建立对象。
32、限制某个类只能在堆中产生:把这个类的析构函数放在priveate里,写一个伪析构函数,这样就不能不采用new来构造这个实例了(因为没有析构).
限制某个类只能在堆上分配,将operator new()放在private中,因为new时都要调用oparator new()。
33、不要返回函数内部用new 初始化的指针的引用
34.包含库文件的顺序要从特殊到一般:本地目录头文件-自己的库文件-第三方库-标准C++库文件
35、不允许在头文件中使用using名字空间
36、注意长的参数表,通常这是可以将众多参数变为类,注意长的函数,通常这可以分成许多函数或者类。
37、不要让编译器为我们产生构造、析构、赋值、拷贝构造函数,如果我们不需要就声明为私有,我们要完全掌控自己的类的行为
38、.编译期检查,有些错误在运行时用assert不如在编译阶段就发现它,可以利用这个特性,在编译阶段,大小为0的数组会报错,所以可以定义一个宏或函数
#define STATIC_CHECK(expr) { char unnamed[(expr) ? 1 : 0]; },然后在程序中需要检查expr的地方调用。这样一些简单的检查就可以在编译期间发现