1. 匿名enum的作用,等同于静态常成员变量
class GamePlayer {
private:
enum {NumTurns = 5};
int scores[NumTurns];
};
一般来说static const成员变量在类外进行定义:
class CostEstimate {
private:
static const double FudgeFactor; // 声明式,位于头文件
};
const double CostEstimate::FudgeFactor = 1.35; // 定义式,位于实现文件
2. 用const, enum, inlines代替#define, 将预处理器的需求降低。const可以帮助编译器侦测出错误用法。
3. 对于const对象,编译器强制执行bitwise constness, 但是在编写程序的时候应该使用概念上的常量性,也就是逻辑上的常量性,只要客户端侦测不出对象的改变。将成员变量声明为mutable,来允许const成员函数内部可以改动成员变量。
4. const和non-const的成员函数可以被重载。
5. const可以作用于类的静态成员(详见1),类的非静态成员(只能于构造函数的初始化列表中进行初始化,之后不能再被赋值),类的非静态成员函数(见3),但是不能作用于类的静态成员函数。原因是类的静态成员函数独立于对象实例,而const成员函数针对对象,两者概念上是互斥的。
6. 构造函数应使用成员初始化列表,顺序最好与声明顺序一致,避免可能存在的错误。
7. Lasy singleton模式是线程不安全的:
class Tool {
public:
static Tool& getInstance()
{
if (tool == NULL) {
tool = new Tool;
}
return *tool;
}
private:
Tool();
~Tool();
Tool(const Tool&);
Tool& operator=(const Tool&);
private:
static Tool* tool;
};
当两个线程都通过判断tool==NULL那么两个线程都会产生实例。
线程安全的单例模式实例:
class Singleton{
public:
static Singleton& getInstance(){
static Singleton singleton;
return singleton;
}
private:
Singleton();
~Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
8. 复习友元函数
class TestFriend { friend int incId(const TestFriend&); friend int getId(const TestFriend&); friend class C; public: TestFriend(): id(0) {} TestFriend(int i) : id(i) {} TestFriend(const TestFriend& tf) : id(tf.id){ } ~TestFriend(){} const TestFriend& operator=(const TestFriend& tf) { if (&tf == this) return *this; this->id = tf.id; return *this; } private: int id; }; class C { public: int getBid(const TestFriend& tf) { return tf.id; } }; int incId(const TestFriend& tf) { return tf.id + 1; } int getId(const TestFriend& tf) { return tf.id; } int main(int argc, char *args[]) { TestFriend tf = TestFriend(5); cout << incId(tf) << endl; TestFriend tf1(tf); cout << getId(tf1) << endl; C cc; cout << cc.getBid(tf) << endl; system("pause"); return 0; }
友元函数:普通函数对一个类的私有或保护成员进行访问友元类:将A声明为B的友元类,使得A的成员函数可以访问B的私有或者保护成员
9. 拷贝赋值函数的返回值为引用,可以支持如下链式表达式:
将myString4赋值给myString3(myString3 = myString2) = myString4;
如果没有声明为引用,那么myString4没有改变myString3对象的内容,因为myString4赋值给了一个临时MyString对象
但是当返回值声明为const引用,那么如上表达式不能通过编译。因为myString3的值不应被改变。