【EffectiveC++】让自己习惯C++
前言 不论你的编程背景是什么,C++都可能让你有点儿熟悉。它是一个威力强大的语言,再夸张一点它好比原子弹,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方法。
- (条款一)视C++为一个语言联邦
- (条款二)尽量以const、enum、inline替换#define
- (条款三)尽可能使用const
- (条款四)确定对象被使用之前已被初始化
不论你的编程背景是什么,C++都可能让你有点儿熟悉。它是一个威力强大的语言,再夸张一点它好比原子弹,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方法。
(条款一)视C++为一个语言联邦
C++一开始只是在C上面加了一些面向对象的特性,最初的名称C with Classes也反映了这个血缘关系。但当这个语言变得成熟起来,它变得更活跃更无拘无束,更大胆的冒险。Exceptions对函数的结构化带来不同的做法,templates将我们带到了新的设计思考方式,STL则定义了一个前所未有的延伸性的做法。今天的C++已经是个多重泛型编程语言,最简单的方法是将其视为一个由相关语言组成的联邦而非单一语言。为了理解C++,你必须认识其只要的次语言,幸运的是总共只有四个:
- C。说到底C++任是以C为基础。区块、语句、预处理器、内置数据类型、数组、指针等统统来自C。C的局限:没有模板,没有异常,没有重载。
- Object-Oriented C++。这部分也是C with Classes所诉求的:classes(包括构造和析构函数),封装(encapsulation)、继承(inheritance)、多态((polymorphism)、virtual函数、…等等。这一部分是面向对象设计之古典守则在C++上的最直接实施。
- Template C++.这是C++的泛型编程部分,也是大多数程序员经验最少的部分。
- STL。它是temolate程序库,看名称也知道,但它是非常特殊的一个。它对容器、迭代器、算法以及函数对象的规约有极佳的紧密配合与协调,STL有自己特殊的办事方式,所以你必须遵守它的规约。记住这四个语言,当你从某个语言切换到另一个,导致高效守则要求你改变策略时,不要感到惊讶。因此我说,C++并不是一个带有一组守则的一体语言;它是从四个次语言组成的联邦政府,每个语言都有自己的规约。记住这四个次语言理解C++就容易得多了!
(条款二)尽量以const、enum、inline替换#define
这个条款或许改为“宁可以编译器替换预处理器”比较好,因为或许#define不被视为语言的一部分,那么正是它的问题所在。有了const、enums和inline,我们对预处理的需求降低了,但并非完全消除。#include仍是必需品,而#ifdef/#ifnfef也继续扮演控制编译的重要角色。目前还不到预处理器全面引退的时候,你应该明确地给予它更长的假期。
(条款三)尽可能使用const
const是一件奇妙事情是,它允许你指定一个语句约束,而编译器会强制实施这项约束。它允许你告诉编译器和其他程序员某值应该保持不变。
请记住:
- 将某些东西声明为const可以帮助编译器侦测承包户错误用法。
- 编译器强制执行bitwish constness,但你编写程序时应该使用“概念上的常量性”。
- 当const和non-const有着实质性等价的实现时,lingwoinon-const版本调用const版本课避免代码重复。
(条款四)确定对象被使用之前已被初始化
为避免在对象初始化之前过早地使用他们,你需要做三件事。第一,手工初始化内置型non-number对象。第二,使用成员初始列对付对象所以成分。第三,在“初始化次数不确定性”氛围下加强你的设计。
请记住:
- 为内置型对象进行手工初始化,因为C++不保证初始化它们。
- 构造函数最好使用成员初始列,而不要在构造函数本体内使用赋值操作。初始列列出的成员变量,其排次序应该和它们class中的声明次序相同。
- 为避免“跨单元之初始化次序”问题,请以local static对象替换non-local static对象。