Effective C++学习(一)

1.让自己习惯C++

一.条款01:视C++为一个语言联邦

(1)C++是个多重范型的语言(multiparadigm programming language),一个同时支持过程形式(procedural)、面向对象形式(object-oriented)、函数形式(functional)、泛型形式(generic)、元编程形式(metaprogramming)的语言
(2)C++并不是一个带有一组守则的一体语言,它一共由四个次语言组成。

  • C
  • Object-Oriented C++
  • Template C++
  • STL
    每个次语言都有自己的规约。

二、条款02-尽量以const/enum/inline替换#define

(1)条款二等价于宁可以使用编译器替换预处理器。
(2)下面第一条所使用的名称ASPECT_RATIO有可能没有进入记号表(symbol)

#define ASPECT_RATIO 1.653;//#define 不能提供任何封装性。
替换为
const double AspectRation=1.653;

(3)有了consts/enums/inlines,我们对预处理器(特别是#define)的需求降低了,但并非完全消除。#include仍然是必需品,而#ifdef/#ifndef也继续扮演控制编译的重要
(4)

  • 对于单纯常量,最好以const对象或enums替换#define
  • 对于形似函数的宏(macros),最好改用inline函数替换#defines。

三、条款03-尽可能使用const

(1)

char greeting[] = "Hello";
char *p = greeting;
const char *p = greeting;//const出现在*左边,定义了个常量数据(常量指针)
char* const p = greeting;//const出现在*右边,定义了的指针是常量(指针常量)
const char * const p = greeting;//const出现在*的左右,指针和数据都是常量

(2)
令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性;const成员函数,第一可以使class接口比较容易理解,这是因为得知哪个函数可以改动对象内容而哪个函数不行,很是重要的。第二,它们使“操作const对象"成为可能。
(3)成员函数如果是const,有两个流行概念:bitwise constness(又称physical constness)和logical constness;const成员函数不可以更改对象内任何non-static成员变量;关键字mutable可释放掉non-static成员变量的bitwise constness约束。

四、条款04-确定对象被使用前已被初始化

(1)对于无任何成员的内置类型,你必须手工完成初始化。至于内置类型以外的,初始化的责任落在构造函数身上。规则很简单:确何每一个构造函数都将对象的每一个成员初始化
(2)所以尽量使用初始化列表(member initialization list),而不使用赋值初始化。初始化列表单只调用一次copy构造,而赋值初始化则要调用一次default构造和一次copy assignment操作符。显然使用初始化列表是比较高效的
(3)C++有着十分固定的“成员初始化次序”。次序总是相同:base classes更早于其derived classes被初始化,而class的成员变量总是以其声明次序被初始化(即使它们在初始化列表中以不同的次序出现,也不会有任何影响),所以初始化列表最好是其成员变量声明顺序,以免出现晦涩错误(是指两个成员变量的初始化带有次序性。如初始化array时需要指定大小,因此代表大小的成员变量必须先有初值)
(4).C++对“定义于不同的编译单元(是指产出单一目标文件的那些源码。基本上它是单一源码文件加上其所含入的头文件[#include files])内的non-local static对象”的初始化相对次序并无明确定义。可将non-local static对象般到自己的专属函数内,变为local static对象。这些函数返回一个reference指定它所含的对象。然后用户用这些函数,而不直接指涉这些对象。这也是Design Patterns里Singleton模式的一个常见手法。这个手法的基础在于:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。但是从另一个角度看,这些函数“内含static对象“的事实使它们在多线程系统中带有不确定性。任何一种non-const static对象,不论它是local或non-local,在多线程环境下“等待某事发生”都会有麻烦。处理这个麻烦的一种做法是:在程序的单线程启动阶段手工调用所有reference-returning函数,这个消除与初始化有关的“竞速形势”

你可能感兴趣的:(Effective,C++)