在c和c++ 中,使用为初始化的类型常常会引发不可预料的错误,从而使得我们要花费巨大的时间用于调试查找问题,所以确定对象被使用前已被初始化是个很好的习惯。
永远在使用之前对对象进行初始化。对于无任何成员的内置类型,你必须手工完成初始化操作。因为c++不保证初始化他们。
内置类型意外的其他东西,初始化责任落在构造函数身上。但要注意区分构造函数中的变量是赋值还是初始化。举个例子
class PhoneNumber{...}; class ABEntry{ public: ABEntry(const std::string &name, const strd::string& address, const std::list<PhoneNumber>& phones); private: std::string theName; std::string theAddress; std::list<PhoneNumber> thePhones; int numTimesConsulted; }; ABEntry::ABEntryconst std::string &name, const strd::string& address, const std::list<PhoneNumber>& phones) { theName = name; //这些都是赋值 theAddress = address; //而非初始化 thePhones = phones; //注意区分 numTimesConsulted = 0; }
ABEntry构造函数一个极好的写法是用member initialization list(成员初值列表),具体如下:
ABEntry::ABEntryconst std::string &name, const strd::string& address, const std::list<PhoneNumber>& phones) :theName(name), theAddress(address), thePhones(phones), numTimesConsulted(0) {}
有些情况下,即使变量属于内置类型也一定要用成员初值列表,例如成员变量是const或references,他们不能被赋值,只能被初始化。
classes拥有多个构造函数,且每个构造函数都有自己的成员初值列表时怎么办?
如果classes存在许多成员变量或base classes , 会导致许多重复的初值列,同时也加重了开发人员的工作。这种情况下可以在初值列中遗漏那些“赋值像初始化一样好”的成员变量,改为赋值操作,并将赋值操作移往某个函数内(通常是private 函数),供所有构造函数使用。这样就可以省去很多无谓的重复劳动。
下面我们来说一说成员初始化的次序。c++中成员初始化的次序总是相同的:base classes早于derived classes被初始化,class成员总是按照声明次序进行初始化。所以为了避免不必要的麻烦,成员初值列的顺序最好与声明顺序一致。
参考自《effictive c++ 》
[effictive c++] 条款04 确定对象被使用前已被初始化
原文:http://blog.csdn.net/chenlei0630/article/details/39339691