effective c++ (二)

条款04:确定对象使用前已先被初始化

1、由于 c part of c++而且初始化可能导致运行期成本,那么就不保证发生初始化;例如arry是c part of c++的部分从而不能保证初始化,而STL的vector则可以保证初始化

2、由于规则复杂多变,故最佳处理办法就是:永远在使用对象之前将它初始化

3、由于C++规定对象成员的初始化动作发生在进入构造函数本体之前,故在构造函数中给定成员初值不是成员变量初始化,而是赋值动作。(C++类成员变量初始化发生于这些成员变量的default构造函数被自动调用之时,但是此规则不适用与C内置类型,因为内置类型没有default构造函数)

class PhoneNumber { ... };
class ABEntry 
{
public:
    ABEntry(const std::string &name, const std::string &address, const std::list<PhoneNumber> &phones)  ;

private:
    std::string theName;
    std::string theAddress;
    std::list<PhoneNumber> thePhones;
    int numTimesConsulted;
};

ABEntry::ABEntry(const std::string &name, const std::string &address, const std::List<PhoneNumber> &phones)
{
    theName = name;   //注意:此处已经是赋值,而非初始化
    theAddress = address;
    thephones phones;
    numTimesConsulted =0;
}



ABEntry::ABEntry(const std::string &name, const std::string &address, const std::List<PhoneNumber> &phones)
:theName(name), theAddress(address), thePhones(phones), numTimesConsulted(0)
{}
View Code

4、使用初始化列表相当于只用了一次copy函数,而使用构造函数给定初值相当于先调用成员变量的构造函数然后调用copy assignment

5、const与reference类型的成员变量必须使用初始化列表初始化(建议:为了避免区分,可以总是采用成员初始化列表书写构造函数,即使无参构造函数也可以)

6、C++有着十分固定的成员初始化顺序:base class更早于derived classes被初始化, 而class的成员变量总以其声明次序初始化

7、non-local static  在不同的编译单元的初始化次序存在不确定性,尽量使用local static 代替non-local static 

class FileSystem{ ... ... }
FileSystem &tfs()
{
    static FileSystem fs;
    return fs;  
}

class Directory { ... ... }
Directory::Directory(params)
{
    std::size_t disks = tfs().numDisks();  
}

请记住:

1、为内置型对象进行手工初始化,因为c++不保证初始化它们

2、构造函数最好使用初始化列表,不要在构造函数本体内进行赋值,且初始化列表顺序应该与声明顺序保持一致

3、为免除“垮编译单元的初始化次序”问题,用local-static代替non-local static

条款05:了解C++默认编写并调用哪些函数

1、如果你自己没有声明,编译器将自动为类声明一个copy构造函数、一个copy assignment操作符和一个析构函数、以及default构造函数。(注意:自动声明的函数都是public且inline)

2、注意copy assignment操作符不是总是生成的,在以下三种情况编译器会拒绝自动生成copy assignment操作符:

  a、类中含有reference成员(因为c++不允许改变引用变量)

  b、内涵const 成员变量

  c、base class将copy assignment操作符声明为private

条款06:若是不想使用编译器自动生成的函数,就该明确拒绝

1、将copy函数或这copy assignment声明为private(注意:其member函数和friend函数还是能够调用)

2、继承Uncopyable这样的base class 

class Uncopyable
{
pretected:
     Uncopyable() {}
     ~Uncopyable {}
private:
    Uncopyable(const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);        
}
原文地址:https://www.cnblogs.com/penghuster/p/6107756.html