想想自己一段时间没有写博客,据说好记性不如烂笔头。开始自己的博客之旅。
最近在看Effective.C,感觉受益颇深,写写博客以后方便回忆。
条款01:视C++为一个语言联邦。
我们可以将C++视为一个由相关语言组成的联邦而非单一语言。
以下分为4类次语言:
1.C。以C为基础。包括区块、语句、预处理器、内置数据类型、数组、指针。
2.Object-Orientd C++。C with classes。包括classes、封装、继承、多态、virtual (动态绑定)。
3.Template C++ 。C++的泛型编程部分。也就是Template。
4.STL。STL是个template 程序库,内有容器、迭代器、算法、函数对象等。
请记住:C++高效编程守则视状况而变化,取决于你使用C++的哪一部分。
条款02:尽量以const、enum、inline 替换#define。
其意义为“宁可以编辑器替换预处理器”。
1.const std::string authorName(“Scott Meyers”)比const char* const authorName=“Scott Meyers” 更好。
2.class 专属常量。将成员声明为static
class GamePlayer
{
private:
static const int NumTurns = 5;
int scores[NumTurns];
}
并在定义式中声明:
const int GamePlayer::NumTurns;
如果不想让别人获得一个pointer 或reference 指向你的某个整数常量,可以采用enum
class GamePlayer
{
private:
enum { NumTurns = 5};
int scores[NumTurns];
}
3.#define的实现宏有时会带来额外的开销,所以可以采用inline来代替一些函数。请记住:对于单纯常量,最好用const 对象或enums 替换#defines 。
对于形似函数的宏,最好改用inline函数替换#defines。
条款03:尽可能使用const
1.char greeting[] = "Hello";
char* p = greeting; //non-const pointer,non-const data
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
///
2.STL 迭代器:
std::vector<int>vec;
...
const std::vector<int>::iterator iter = vec.begin();//iter的作用像个T*const
*iter = 10 ; //没问题,改变iter所指物
++iter; //错误!iter 是const
std::vector<int>::const_iterator citer = vec.begin();//citer的作用像个const T*
*citer = 10 ; //错误!*cIter是const
++citer; //没问题,改变cIter
3.const 可以降低因客户错误而造成的意外。4.const成员变量。对于bitwise constness 阵型来说,要求编译器和调用者都遵循bitwise constness 的原则,不能去改变成员变量的任何意外,但可能会造成一些错误。
从而有了logical constness 阵型,允许编写类的程序员有意识的使用matable 关键字来让const 成员函数改变这些值,但前提是不能让类的使用者知道其中改变的方法。
如:
class CTextBlock {
public:
...
std::size_t length() connst<span style="white-space:pre"> </span>
private:
char *pText;
mutable size_t textlength; //这些成员变量肯呢过总是会被改变,即使在const 成员函数内
mutable bool lengthIsValid;
};
std::size_t CTextBlock::length() const
{
if (!lengthIsValid) {
<pre name="code" class="cpp"> textlength = std::strlen(pText);<span style="font-family: Arial, Helvetica, sans-serif;"> // 现在合法</span>
lengthIsValid = true; // 同样合法 } return textLength;}
5.const 和 non - const 成员函数中避免重复。
class TextBlock{
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 TextBolck&>(*this)[position]);
}
}
这里先将*this 从其原始类型 TextBlock& 转型为 const TextBlock&。const_cast 用来移除const,最后返回。
而反向做法将non-const 转为const是不行的。
请记住:将某些东西声明为const 可帮助编译器侦测错误用法。const 可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)。
当const 和non-const 成员函数有着实质等价的实现时,令non-const 版本调用const 版本可避免代码重复。