C++规定对象的初始化动作发生在进入构造函数主体之前。(初始化列表比在构造函数体内初始化的效率高,以为在函数体内初始化会调用默认的构造函数)
创新互联建站-专业网站定制、快速模板网站建设、高性价比泰安网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式泰安网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖泰安地区。费用合理售后完善,10多年实体公司更值得信赖。编译单元是指产出单一目标文件的那些源码。
问题:
两个源码文件,每个文件中至少有一个non-local static对象(即该对象是全局的或者位于namespace作用域内,或在class内或file的作用域内被声明为static)。如果某编译单元内的non-local static对象的初始化用动作使用了另一个单元内的某个non-local static对象,在这个时候由于c++对定义在不同的编译单元内的non-local static对象的初始化次序没有明确的规定,所以用可能引发错误。
例子:
你写的程序(一个编译单元):
class FileSystem { public: … size-tnumDisk() const; … };
Extern FileSystem tfs;// 准备给别人用的对象
别人的程序(另一个编译单元)
class Directory { Directory(params) { Size_tdisk=tfs.numDisks(); //使用第一个编译单元的对象,假设在编译这个文件之//前已经编译了上一个文件那么没错,如果相反呢? } };
解决办法:
将每个non-local static对象搬到自己专属的函数内(也就是在函数内声明为static)。这些函数返回一个引用指向它所含的对象。在调用的时候调用这些函数而不是直接调用对象。理由(c++保证,函数内的local static对象会在该函数调用期间首次遇上该对象的定义式时被初始化)
程序修改之后:
class FileSystem { public: … size-tnumDisk() const; … }; FileSystem& tfs() { static FileSystem fs; returnfs; } Class Directory { Directory(params) { Size_tdisk=tfs().numDisks(); //调用函数tfs() } }; Directory& tempDir() { Static Directory td; return td; }
任何一种non-conststatic对象不论他是local还是non-local,在多线程的环境下等待某事发生都会有麻烦,处理麻烦的做法是:在程序单线程启动的阶段手工调用引用返回的函数,这可以消除与初始化有关的竞速形式。
总结:
一、对内置类型进行手工初始化(c++不保证初始化他们)。
二、构造函数最好使用成员初始列,而不要在构造函数内使用赋值操作,初始列的次序应该和class中的声明次序相同。
三、为免除跨编译单元的初始化问题,应该用local static对象替换non-local static对象。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。