簡體   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