effect C++ 确定对象被使用前先被初始化
来源:互联网 发布:初中考试软件 编辑:程序博客网 时间:2024/06/05 14:12
将对象初始化
int x 在某些语境下x保证初始化(为0),但在其他语境中却不保证。
class Point{ int x , int y;} .... Point p ;
p的成员变量有时候初始化(为0),有时不会。读取未初始化的值会导致不明确行为。最佳的处理办法就是:永远在使用对象之前将他们初始化。对于无任何成员的内置类型,必须手工完成此事。
int x =0; const char * text ="A-C-style string";double d ;std::cin>>d; //以读取input stream的方式完成初始化
确保每一个构造函数都将对象的每一个成员初始化。
注意别混淆了赋值和初始化。
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;}
C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前
较佳的一个写法是:
ABEntry::ABEntry(const std:: string &name,const std::string&address, const std::list<PhoneNumber>&phone):theName(name),theAddress(address),thePhones(phones),numTimesConsulted(0) //这些都是初始化{}通常效率更高,基于赋值的那个版本首先调用default构造函数为成员赋初值,然后立刻重新赋值。
总使用成员初值列。
不同编译单元内定义之non-local static 对象
static对象 ,其寿命从构造出来直到程序结束为止(stack和heap-based对象都被排除)。这种对象包括global对象,定义于namesapce作用域的对象、在classes内、函数内、以及在file作用域内被声明为static的对象。 函数内的static对象被称为local static对象(因为它们对函数而言是local),其他的对象称为non-local对象。程序结束时static对象会被自动销毁,它们的析构函数会在main()结束时调用。
编译单元是产出单一目标文件的那些源码,基本是单一源码加上其所含入的头文件。
现在至少有两个源码文件,每一个内含至少一个non-local static 对象(也就是该对象是global或位于namespace作用域内,抑或在class内或file作用域内被声明为static)。真正的问题是:如果某编译单元内某个non-local static对象的初始化动作使用了另一编译单元内的某个non-local static对象,它所用到的这个对象可能未被初始化。
例:
class FileSystem{public:...std::size_t numDisks()const; //众多成员函数之一...}extern FileSystem tfs; //预备给客户使用的对象假设用户建立一个classclass Directory{public: Directory(params); ...};Directory::Directory(params){ ... std::size_t disks=tfs.numDisks(); //使用tfs对象 ...}如果客户决定创建一个Director对象Director tempDir (params);除非tfs在tempDir之前被初始化,否则tempDir的构造函数会用到尚未初始化的tfs。它们是定义在不同编译单元内的non-local static 对象。
解决:
将每个non-local static 对象搬到自己的专属函数内(该对象在此函数内被声明为static)。这些函数返回一个reference 指向它所含的对象。然后用户调用着这些函数,而不是指涉这些对象。 non-local static 对象被 local static 对象替换了。(Singleton模式的一个常见的实现手法)C++保证,函数内的local static 对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。所以如果以“函数调用”(返回一个reference指向local static对象)替换“直接访问non-local static对象”,就可以保证获得的那个reference将指向一个历经初始化的对象。如果从未调用 non-local static 对象的“仿真函数”,就绝不会引发构造和析构成本。
class FileSystem{...} //同前FileSystem& tfs() //这个函数用来替换tfs对象;它在FileSystem class 中可能是个static{ static FileSystem fs; //定义并初始化一个local static对象 return fs; //返回一个reference指向上述对象}class Directory{...}; //同前Directory::Directory(params){ ... std::size_t disks =tfs().numDisks();//原本的reference to tfs现在改为tfs()}Directory&tempDir() //这个函数用来替换tempDir对象,它在Directory中可能是一个static { static Directory td; //定义并初始化local static 对象 return td; //返回一个reference指向上述对象}
这样,客户使用tfs()和tempDir()而不再是tfs和tempDir,使用的是指向static对象的reference
为内置型对象进行手工初始化,因为C++不保证初始化它们。
构造函数最后使用成员初值列,而不要在构造函数本体内使用赋值操作。初值列列初的成员列表,其排列次序应该和它们在class中声明的次序相同。
为免除“跨编译单元之初始化次序”问题,请以local static 对象替换non-local static 对象。
- effect C++ 确定对象被使用前先被初始化
- 《Effect C++》学习------条款04:确定对象被使用前以先被初始化
- Effective C++(4) 确定对象被使用前已先被初始化
- Effective C++:条款04:确定对象被使用前已先被初始化
- [Effective C++]条款04 确定对象被使用前已先被初始化
- [effictive c++] 条款04 确定对象被使用前已被初始化
- 确定对象被使用前巳先被初始化
- 《Effective C++》学习笔记条款04 确定对象被使用前被初始化
- 重读经典-《Effective C++》Item4:确定对象被使用前已先被初始化
- 读书笔记《Effective C++》条款04:确定对象被使用前已先被初始化
- 条款4:确定对象被使用前已经被初始化
- effective c++ 确定对象被使用前已经被初始化
- 确定一个对象在使用前已经被初始化
- 条款04:确定对象被使用前已先被初始化
- 条款04:确定对象被使用前已先被初始化
- 条款4:确定对象被使用前已先被初始化
- EffictiveC++之确定对象在使用前被初始化
- Effective C++ Item 4 确定对象被使用前已先被初始化
- 个人论文用到的图表,备份一下
- Http文件断点下载(Http请求头的Range字段)
- csdn中如何查看排名
- 如何在数据库中存储一棵树
- Java 面向对象基础
- effect C++ 确定对象被使用前先被初始化
- Android数据存储3种方式
- 移动零
- Chrome DevTools 中文文档
- 记录下 用数字对应EXECEL表头的字母
- Unity3D_uGUI学习笔记(5)_Animation Integration简述
- 大数据相关资源
- kafka跟storm收集日志解决方案
- swap file “*.swp”already exists