Effective C++: Item01 ~ Item04

Item01:C++是一门多范式编程语言

  • 面向过程
  • 面向对象
  • 泛型编程
  • STL

Item02:尽量以const、enum、inline替换#define

  • #define 是由预编译器处理的,所以定义的一些常量名不会出现在编译阶段的符号表里,这样在编译报错的时候,定位出错位置将耗费时间。

    推荐:使用const常量替代#deifine定义常量。

  • 当类的普通成员需要依赖于类的静态成员时,可以使用enum替代。

    class GamePlayer 
    {
    public:	
        static int number;
    	enum { NUM = 10 };
    	int scores[NUM]; // 这里的NUM不能使用static成员实现,因为类定义中静态成员只是声明,静态成员的实现是在类外部。
    };
    int GamePlayer::number = 10;
    
  • #define经常被用来实现宏函数,但是因为它只是单纯的文本的替换,所以使用要十分小心。

    推荐:使用inline替代宏函数。

Item03:尽可能使用const

  • const修饰指针变量时,在*左边表示指针所指的内容不可变,在右边表示指针自身不可变。

  • const可以修饰一个函数的返回值、参数、函数自身(成员函数)。

    class Rational { ... };
    const Rational operator* (const Rational &lhs, const Rational &rhs);
    // 返回const修饰的返回值,可以避免以下情况的发生:
    Rational a, b;
    (a * b) = c; // error, (a * b)的结果是const的
    // 这有利于在条件判断中将==误写为=时及时发现错误
    
  • const成员函数和non-const成员函数可以构成重载,在对const对象调用函数时,调用const成员函数。

  • 通过向成员变量添加mutable修饰符,使得const成员函数内部可以修改成员变量。

  • 当const和non-const成员函数有着实质等价的实现时,令non-const调用const版本可以避免代码重复。

Item04:确定对象在使用之前已被初始化

  • 在类的构造函数内完成所有成员(内置类型和自定义类型)的初始化(使用初始化列表,而不是在构造函数中赋值)。

  • 注意区分初始化和赋值的区别。

  • 基类的初始化总是优先于派生类的初始化,成员变量的初始化顺序与声明的顺序相同。

  • 编译单元:产出单一目标文件的源码。

  • 无法确定不同编译单元内non-local static对象的初始化顺序。

    B b; // B是另一个文件中的全局变量(non-local static)
    
    
    class A
    {
    public:
    	A() { b.init(); } // 这里在调用的时候,并不能保证b已经初始化了	
    };
    

    解决办法:通过定义一个函数将non-local static对象作为返回值返回。

    B& getB()
    {
    	static B b;
        return b;
    }
    
    // 在A中通过getB()就可以获得初始化后的对象。
    

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