The best way to deal with this seemingly indeterminate state of affairs is to always initialize your objects before you use them. For non-member objects of built-in types, you’ll need to do this manually. For example:
- int x = 0; // manual initialization of an int
- const char * text = "A C-style string"; // manual initialization of a
For almost everything else, the responsibility for initialization falls on constructors. The rule there is simple: make sure that all constructors initialize everything in the object.
The rule is easy to follow, but it’s important not to confuse assignment with initialization. Consider a constructor for a class representing entries in an address book:
- class PhoneNumber { ... };
- class ABEntry { // ABEntry = “Address Book Entry”
- 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; // these are all assignments,
- theAddress = address; // not initializations
- thePhones = phones;
- numTimesConsulted = 0;
- }
大部分情况下,我们已经不再需要逐条指令、每个时钟周期地去推敲代码的执行性能。即使你有强迫症,非要这样做,许多现代CPU(尤其是复杂指令集的CPU)的工作方式也不能精确地保证每条指令到底需要多长时间完成。所以,即便你觉得某处变量声明处的初始化过程不必要,也最好养成习惯去初始化变量。
当你把编译器的警告开关打开(以我最常用的编译器gcc为例),编译器通常会检查出那些可能未被初始化就开始使用的变量。你可以强迫编译器在警告的同时停止编译,这么做可以帮助你培养出初始化变量的好习惯。