《Effective C++》读书笔记(1)
让自己习惯C++
条款01:视C++为一个语言联邦
- C++ 高效编程守则是状况而变化,取决于你使用C++的哪一个部分。
C++并不是一个单一范式编程语言,它同时支持过程形式(procedural),面向对象设计(object-oriented)、函数形式(functional)、泛型形式(generic),元编程形式(meta-programming)。
所以作者认为并不是每一个规则都是适用于所有的这些范式的,那么我们可以将C++语言分为一下几种次语言:
- C
- Object-Oriented C++
- Template C++
- STL
条款02:尽量以const,enum,inline替换#define
- 对于单纯常量,最好以const对象或enums替换#define
- 对于形似函数的宏(macros),最好改用inline函数替换#define
#define的缺点:
- define 定义的值无法被编译器和调试器看到,出问题了很麻烦。
- 没有良好的封装新,不能控制作用域。
const
使用const我可以这样声明一个常量:
1 | const std::string ProductName("Mango Game"); |
还可以声明一个类的专属常量:
1 | //Header |
enum hack
如果需要编译时使用到常量就需要enum hack这个技巧,实现如下:
1 | class GamePlayer { |
inline function
有一些宏长得很像函数,这种宏有类型安全问题和不可预料行为两个问题。可以使用inline function来替代。
1 | //这个MAX宏很不好,会出现奇怪的一些问题且无法调试 |
条款3:尽可能使用const
- 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
- 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)。
- 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
const提供一种语义上的约束,它能够约束变量使用者的行为。当它作用于针、智能指针、迭代器上的时候可以指向指针本身也可以是指针指向物。作者提出了一个识别的技巧:如果关键字const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针本身是常量。
例子:
1 |
|
有点头晕,我有一个不是很恰当地记忆方法。可以把const
看成修饰它右边所有内容的,以const char* p
为例,把p
看成一个指针,而*p
则是数据,所以const
是修饰数据的。而char * const p
中,const
右边只有p
,所以它只是限制指针本身的。
bitwise constness vs logical constness
当限制一个成员函数为const,编译器会执行bitwise constness,即检查函数内部是否修改了类的成员变量。但是写代码的时候应该注意逻辑上的常量限制,比如说一个你返回了一个指向内部变量的指针,这个函数虽然符合编译器的const限制但却不是很好的一个写法。
[to be continued]