Effective C++笔记
第一章 00~04
p0:导读
1:构造函数声明为explict,可以禁止编译器执行非预期的类型转换(阻止隐式转换,但可以显式转换)。
2:copy构造函数 用来”以同类型对象初始化自我对象”
copy赋值操作符 用来”从另一个同类型对象拷贝其值到自我对象”。
两者区别在于如果一个新对象是被定义,一定会调用一个构造函数,不可能是赋值操作,
如果没有新对象被定义,那就是赋值操作被调用。
Widget w1;
Widget w2(w1); //copy构造函数
Widget w3 = w2;//copy构造函数
w1 = w2; //copy assignment操作符
p1:视C++为一个语言联邦
四个模块:C, object-oriented C++, template C++, STL
高效:内置类型传递使用值传递,自定义类型使用引用传递。
p2:尽量用 const ,enum , inline 替换 #define
1:定义常量指针 const char* const authorName = “Sping”;
const std::string authorName(“Sping”);
2:class 专属常量
//.h
class GamePlayer
{
private:
static const int NumTurns = 5; //1:常量声明
static const int NumTurn; //2:常量声明
int scores[NumTurns];
};
//.cpp
const int GamePlayer::NumTurns; //1:常量定义 //对于class专属常量,如果是整数类型并且不需要取地址的话可以不定义。
const int GamePlayer::NumTurn = 5;//2:常量定义
3:一个属于枚举类型的数值可权充ints使用, 比如常见的对话框资源ID。
class Game
{
private:
enum { NumTurns = 5 };
int scores[NumTurns];
};
4:使用 template 替换宏定义
//如以a和b的较大值调用f函数
#define CALL_WITH_MAX(a,b) f( (a)>(b) ? (a):(b) )
template <typename T>
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
p3:尽可能使用const
1:指针指向常量 与 常量的指针
const在左边,表示被指物是常量;const在右边,表示指针自身是常量;
char greeting[] = "Hello";
const char* p = greeting; //no-const *p, const data
char* const p = greeting; //const *p, no-const data
2:声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
3:成员函数如果只是常量性不同,可以被重载
4:mutable(可变的),关键字mutable释放掉non-static成员变量的bitwise constness约束。
5:当const和 non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
class TextBlock
{
public:
const char& operator[](std::size_t position) const{
return text[position];
}
char& operator[](std::size_t positon){
return const_cast<char&>(
static_cast<const TextBlock&>(*this)[position]
) //1:为*this加上const调用const op[];
} //2:将op[]返回值的const转除;
private:
std::string text;
public:
std::size_t length() const;
private:
char* pText;
mutable std::size_t textLength; //最近一次计算的文本长度
mutable bool lengthIsValid; //目前长度是否有效
};
std::size_t TextBlock::length() const
{
if(!lengthIsValid){
textLength = std::strlen(pText);
lengthIsValid = true;
}
}
p4:确定对象呗使用前已先被初始化
1:C++不保证初始化内置类型的对象。
2:对象的成员变量的初始化发生在进入构造函数之前。
3:构造函数最好使用成员初值列,而不要在构造函数中使用赋值操作,初值列的初始化次序只与class中的声明次序一致。
4:为免除”跨编译单元之初始化次序”问题,应以local static对象替换non-local static对象。
FileSystem& tfs()
{
static FileSystem fs; //函数内的static对象称为local static。
return fs;
} //也即是设计模式中的单例模式