/* 確保 object 在被使用前已初始化 */ // 1. Reading uninitialized values yields undefined behavior // 2. Best: always initialize your objects before you use them // Non-member objects of built-in types int x = 0; const char * text = "A C-style string"; double d; std::cin >> d; // For almost everything else: make sure that all ctor initialize everything in the object class PhoneNumber {}; class ABEntry { public: ABEntry(); ABEntry(const string& name, const string& address, const std::list<PhoneNumber> &phones); private: std::string theName; std::string theAddress; std::list<PhoneNumber> thePhones; int numTimesConsulted; }; ABEntry::ABEntry(const string& name, const string& address, const std::list<PhoneNumber>& phones) { theName = name; theAddress = address; thePhones = phones; numTimesConsulted = 0; // these are all assignments not initializations } // 1. The data members of an object are initialized before the body of a constructor is entered. // 2. Use the member initialization list instead of assignments: more efficient ABEntry::ABEntry(const string& name, const string& address, const std::list<PhoneNumber>& phones) :theName(name), theAddress(address), thePhones(phones), numTimesConsulted(0) // these are now all initializations {} // Default-construct a data member ABEntry::ABEntry() : theName(), theAddress(), thePhones(), numTimesConsulted(0) {} // For data member that are const or are references must be initialized by initialization list // 1. Duplication when multiple ctors: by a single private function that all the ctors call. // 2. In general, true member initialization(via an initialization list) is preferable to pseudo-initialization via assignment // Initialization order: base class before derived class, data member is initialized in the order where they are declared. // 1. Static object: one that exists from the time it's constructed until the end of the program, automatically // destroyed when the program exits, i.e., dtors automatically called when main finishes executing. // 2. local static object: static objects inside functions; non-local static object: others // 3. A translation unit: source code giving rise to a single object file (a single source file + all of its #include files) // 4. 若一個 translation unit 的 non-local static object 之初始化用到另一個 translation unit 中的 non-local static object, 則 // 被使用的 object 可能未被初始化 -> 因為定義在不同 translation unit 的 non-local static objects 之初始化相對順序是未定義的 class FileSystem { public: std::size_t numDisks() const; }; extern FileSystem tfs; class Directory { public: Directory(void * pParams); }; Directory::Directory(void * pParams) { std::size_t disks = tfs.numDisks(); } Directory tempDir(nullptr);// static object: global variable // How can we be sure tfs will be initialized before tempDir? No Way. // Solution: Singleton Pattern FileSystem& tfs() // could be a static member function in the FileSystem class { static FileSystem fs; return fs; } Directory::Directory(void * pParams) { std::size_t disks = tfs().numDisks(); } Directory& tempDir() // could be a static member function in the Directory class { static Directory td; return td; } // 1. If never call, never incur the cost of constructing and destructing the object // 2. Excellent candidates for inlining // 1. Function contain static objects makes them problematic in multi-threaded systems. // 2. Solution: manually invoke all the reference-returning functions during the single-threaded startup portion of the program.
2018年10月22日 星期一
[Effective C++] Make sure that objects are initialized before they're used
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言