effective C++笔记———不同编译单元内定义之non-local static对象的初始化次序问题(真拗口o(╯□╰)o)

首先解释两个概念:
1.编译单元:简单的说,按照C++标准,每一个.cpp文件就是一个编译单元,编译器不会编译.h头文件。
2.static对象:特点:生命周期从创建一直到程序结束为止。包括:全局(global)对象;定义域命名空间(namespace)作用域内的对象;在class内、函数内以及file作用域内被声明为static的对象。
函数内的static对象就叫做:local static对象。除此之外的static对象就是所谓的non-local static对象。
标题的意思,解释下来,就是在两份.cpp源码中,分别包含有一个non-local static对象,恰好这两个对象要初始化的时候又与另外一个有所关联,这时候就会存在一个初始化次序问题。举个例子就是,源码1中定义了nls(non-local static)对象A,源码2中定义了nls对象B,当B要初始化的时候会用到A的成员,如果在B要初始化的时候A还没有初始化,就会报错了。而C++中对于不同源码中的nls对象的初始化次序问题没有明确定义,也就是A和B初始化谁先谁后根本就是无解的。
解决办法:
按照effective C++所述,可以将每个nls对象搬到自己的专属函数内,在此函数内该对象被声明为static,最后函数返回指向这个新的static对象的引用。具体如下例:

class filesystem{
    public:
    ...
    std:size_t fun() const;//众多成员函数之一
    ...
};
extern filesystem A;
class directory{
    public:
    directory(params);
    ...
};
directory::directory(params)
{
    ...
    std::size_t disks=A.fun();//使用A对象
    ...
}

directory B(params);

最后一行代码出现了标题所说的问题,除非A在B之前先被初始化,否则B的构造函数会用到还未初始化的A,但上文已经提到相关的初始化次序是一个无解的问题。
解决办法如下:

class filesystem{...};//同上
filesystem& A()       //这个函数用来替换A对象;它在filesystem class中可能是个static

{
    static filesystem AA;//定义并初始化一个local static对象
    return AA;           //返回一个referen指向上述对象
} 
class directory{...};
directory::directory(params)
{
    ...
    std::size_t disks=A().fun();
    ...
}
directory& B()
{
    static directory BB;
    return BB;
}

这样修改后,按照C++的标准,函数内的local static对象会在该函数被调用期间首次遇到该对象之定义式时被初始化,也就是调用函数A时AA对象将已经完成初始化,即解决了本文所述的次序问题。同时如果从未调用此函数,也绝不会产生构造和析构成本,非常划算。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值