繁体   English   中英

在静态取消初始化期间是否可以保证cout?

[英]Is cout guaranteed available during static deinitialization?

我有一个准单例类(准单例,因为大多数使用是指一个函数是静态的单个对象,但用户也可以构建自己的本地副本以供短期使用)我想写来自其析构函数的cout,并想知道在程序终止后的静态取消初始化阶段是否可以保证cout可用。 这个问题来看似乎答案是肯定的(函数静态初始化对象应该从它们构造时以相反的顺序调用它们,这应该在cout建立之后),但我想检查。

// Count calls to a logging function from some point in our code, to determine
// how many times it gets executed during a run, then report calls at the end
// of the program.  A quick-and-dirty way of determining how often we execute
// code.
class callCounter;
class callCounter {
public:
    callCounter() : has_calls_(false), counts_() {}
    ~callCounter () {report(std::cout);}
    void logCall(const std::string callSite);
    void report(std::ostream &os);
    void reset();
    static callCounter *theCounter();
private:
    typedef std::map<std::string, callCount> COUNTMAP;
    bool has_calls_;
    COUNTMAP counts_;
};

callCounter *callCounter::theCounter()
{
    static callCounter theCounts;
    return &theCounts;
}

典型用法是:

callCounter::theCounter()->logCall("foo");

因此,在析构函数中使用cout保证安全(至少就使用cout本身而言 - 可以说是完全安全的,我应该将报告包装在try块中以防写入抛出异常。)?

简答:是的

答案:是的

标准库使用几个技巧来确保std :: cout(和std :: cin / std:cerr)在任何其他对象之前可用(但是你必须在翻译单元中#include <iostream>) 。 因为它们是首先创建的(破坏规则保证的相反顺序), 所以它们会在您的对象之后被销毁

请参阅:n3242(实际上是C ++ 0x标准Pub:2011-02-28)

27.4标准iostream对象

第2段

构造对象并在第一次构造类ios_base :: Init的对象之前或期间的某个时间建立关联,并且在任何情况下在main主体开始执行之前建立关联。 程序执行期间不会销毁对象。 包含在翻译单元中的结果应该好像<iostream>定义了具有静态存储持续时间的ios_base :: Init的实例 类似地,整个程序应该表现得好像至少有一个具有静态存储持续时间的ios_base :: Init实例。

添加了突出显示。

从n1804(基本上是2003年标准:Pub:2005-04-27)

27.3标准iostream对象

第2段

对相应的宽字符和窄字符流的混合操作遵循与在FILE上混合此类操作相同的语义,如ISO C标准的修订1中所规定的。 构造对象,并且在第一次构建类ios_base :: Init的对象之前或期间的某个时间建立关联,并且在任何情况下在main的主体开始执行之前建立关联。 在程序执行期间不破坏对象280

不幸的是,可以作为保证的位在脚注中(这是非规范性的(即它不能保证实施者应该尝试和实现的内容)。

用脚注:

280)静态对象的构造函数和析构函数可以访问这些对象以从stdin读取输入或将输出写入stdout或stderr。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM