TMP 模板元编程
0.explicit构造函数比non-explicit构造函数好。
1.可以用const 来代替#define 定义一个常量。
#define没有作用域,也没有封装性。
class A { private: static const int NUM=5; //当常量为static且为整数类型,则可将不需定义式。 }; const int A::NUM; //NUM的定义。在声明式中已经获初值,所以无需在定义式给初值。
//当在类中要声明一个长度固定的数组,而旧编译器不能在类中赋初值,所以用enum class A { private: enum{NUM=5}; int array[NUM]; };
但enum不可以取地址,而const 常量能取地址。因此指针或引用不能指向enum常量。
#define定义宏时,可以用template inline函数代替。
#ifdef/#ifndef 很重要。
const vector<int>::iterator pos; //类似T* const 即指向不变
vector<int>::const_iterator pos; //类似const T* 即指向的元素不变。
函数返回值后加const 为了避免意外发生。
const int operator+(const A a,const A b) { return a.num()+b.num(); } int c; a+b=c; //如果函数没加const,则可以错误赋值。 c=a+b; if(a+b=c) //const 可避免此错误
成员函数如果常量性不同就可被重载。
编译器遵循bitwise constness准则。如果想要实现logical constness,则用mutable改变const值
bitwise constness:只要成员函数声明为const,则类中任何一个成员都不能变。
logical constness:对于客户来说不变即可。
当重载成员函数(只有const区别),则非const调用const函数为好,中间可进行强制转换。
在写函数时要考虑const。
面对成员变量为const或reference时,他们一定要初始化列表,而不是赋值。
构造函数用初始化列表初始化。
当构造函数的初始化和赋值效率差不多时,则创建private函数存放共同的部分,在多个构造函数中调用。
当两个类在不同编译单元中,当一个类要用到另一个类对象时,不知道初始化顺序,所以为了确保顺序,必须定义一个函数
#include"A.h" class A { public: size_t numDisk() const; }; #include"B.h" class B { public: //B(params); }; /* B::B(params) { size_t disk=A.numDisk(); //调用时不知道是否已对A初始化 } */
当变为下面时,
/*A& A()
{
static A a;
return a;
}
*/
情况好转。
这就是传说的singleton模式。
class FileSystem { public: size_t numDisk() const; }; extern FileSystem tfs; class Directory { public: Directory(params); }; Directory::Directory(params) { size_t disks=tfs.numDisk(); }
改进版
class FileSystem {}; FileSystem& tfs() { static FileSystem fs; return fs; } class Directory {}; Directory::Directory(params) { size_t disks=tfs().numDisk(); } Directory& tempDir() { static Directory td; return td; }