Effective C++(1)(1~4)
01:视C++为一个语言联邦
四个次语言:
- C
- Object-Oriented C++(面向对象C++)
- Template C++
- STL
02:尽量以 const, enum, inline代替 #define
使用#define时,编译器“看不到”你所define的变量,那么当报错时,为了查找理解你所定义的,就需要耗费大量时间
#define ASPECT_RATIO 1.653 //aspect_ratio并未进入符号表
当以常量代替#define时,有两种特殊情况
- 定义常量指针
const char* const authoerNameo = "ScottMeyers"
- 定义class专有常量
//为了将常量作用域限制于class内,需要static
class GamePlayer{
static const int NumTurns = 5;//常量声明式
int scores[NumTurns];//使用常量
}
对于形似函数的宏(如#definr Test(a,b) f((a)>(b)?(a):(b))),可以用inline代替
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a: b);
}
03:尽可能使用const
const的几种不同用法
char greeting[] = "hewwl"; char* p = greeting; const char* p =greeting; //non-const pointer, const data char* const p = greeting; //const pointer, non-const data const char* const p = greeting; //const pointer, const data //注: const Widget* pw与Widget const* pw等价
令函数返回一个常量值,可以降低因错误而造成的意外,如:
class Rational{};
const Rational operator*(const Rational& lhs, const Rational& rhs);
//如果没有const可能会造成
Rational a,b,c;
if (a*b = c)
{
/* code */
}
另:双目运算符operator*想拥有两个参数,必须在类外定义,因为类内有隐式this指针
当const 和 non-const成员函数有着实质等价的实现时,令non-const版本调用const版本来避免代码重复
class TextBlock { public: const char& operator[](std::size_t position) const{ //过程1 //过程2 //过程3 return text[position]; } char& operator[](std::size_t position){ return const_cast<char&> (static_cast<const TextBlock&> (*this)[position]); } }; //注:不能用const调用non-const,因为non-const可能改变对象
04:确定对象使用前已被初始化
-
为内置对象进行手工初始化
内置对象不进行手工初始化的话很可能得到随机值,而浪费性能
-
构造函数使用成员初始化列表,而不是赋值
class A
{
private:
int member1;
double member2;
std::string member3;
public:
//使用初始值列表
A() : member1(0), member2(0), member3(std::string()){}
//赋值初始化
A(){
member1 = 0;
member2 = 0;
member3 = "";
}
};
使用赋值初始化的构造函数在赋值前还会调用default的构造函数,因此会造成性能流失
-
以本地静态对象代替非本地静态对象
这是为避免跨编译单元初始化次序问题而提出的解决方案,简单来说就是:
//a.cpp
class hen{
public:
std::size_t makeEggs();
};
hen ji;//non-local static
//b.cpp
extern hen ji;
class eggs{
public:
void eggs()
{
ji.makeEggs();
}
};
此时若调用eggs构造函数,而ji未初始化,则会造成严重问题(多编译文件初始化次序不确定)
而
//a.cpp
class hen{
public:
std::size_t makeEggs();
};
hen& chicken()
{
static hen ji
return ji;
};
//b.cpp
extern hen ji;
class eggs{
public:
eggs()
{
chicken().makeEggs();
}
};
不存在问题,原因简单分析:
non-local static 的做法 ——> 调用 eggs 构造函数 ——> 调用 ji.make_egg() ——> 发现 ji对象没有被初始化 —>死亡
local static 的做法 ——> 调用 eggs() ——> 调用 egg 构造函数 ——> 调用 ji() ——> 调用 ji 的构造函数 —> 成功

浙公网安备 33010602011771号