- 对于单纯常量,最好以const对象或enums替换#defines
- 对于形似函数的宏,最好改用inline函数替换#defines
- 尽量使用const
std::vector<int> vec;
// 注意下面的比较
const std ::vector<int>::iterator iter = vec.begin();
*iter = 10; //正确,iter相当于T* const
++iter; //错误,iter本身不能改变
const std ::vector<int>::const_iterator citer = vec.begin();
*citer = 10; //错误,citer相当于const T*
++citer; //正确,citer本身能被改变
const是指不更改对象内的任何一个bit,所以const成员函数不能更改对象内任何非static的成员变量。
//
class CT {
public:
std::size_t length() const;
private:
char* p;
std::size_t = tlength;
mutable bool lengthIsValid;
};
std::size_t CT::length() const{
if(!lengthIsValid){
tlength = std::strlen(p); //错误,const成员函数内不能被改变
lengthIsValid = true; //正确,要改变除非加上mutable关键字
}
}
常量性转移解决常量调用和非常量调用。
// 发生了两次转换:第一次是为*this添加const调用const op[]版本,第二次是从const op[]的返回值中移除const
// static_cast安全,但const_cast存在安全隐患
class CT {
public:
const char& operator[] (std::size_t position) const {
return text[position];
}
char& operator[] (std::size_t position){
return const_cast<char&>(static_cast<const CT&>(*this)[position]);
}
};
- 构造函数最好使用成员初值列,而不要在构造函数的本体内使用赋值操作。如果有出现跨编译单元的初始化次序问题,要使用local static。
- 编译器可以自己为class创造默认构造函数,拷贝构造函数,赋值构造函数和析构函数。
- 将相应的成员函数声明为private并且不要去实现它,可以驳回编译器自动提供的功能(比如赋值,拷贝等)。
- 任何类只要带有virtual函数都几乎确定应该也有一个virtual析构函数。给基类一个virtual析构函数只适用于多态性质的基类。
- 析构函数不要突出异常。
- 在构造函数内对对象调用virtual函数是一种错误的做法。
10.copy函数应该赋值对象内所有的成员变量,包括基类部分,同时不要以某个copy函数去实现另外一个copy函数,应该放进第三个函数中。