2009-11-10 88 views
1

我有一個(簡化)靜態全局類和< <運算符重載如下:爲靜態類重載ostream <<運算符?

class Global 
{ 
    private: 
    static int counter; 
    Global(){}; 

    public: 
    friend ostream& operator<<(ostream &out, Global &global); 
} 

ostream& operator<< (ostream &out, Global &global) 
{ 
    //... do output 
    return out; 
} 

我希望能夠通過一個靜態引用來清點:

cout << Global 

然而,< <運算符需要一個實例,但實際上不存在此全局類的實例。有沒有辦法解決?

感謝您的任何幫助。

回答

4

首先,你不能使用類名作爲值 - 它根本就不是一個值。所以你必須引入一個與<<不同的名字 - 比如global(帶小寫的「g」)。

在一般情況下,如果要在不定義對象推出了「流化」的名字,你應該寫一個流處理器:

std::ostream& foo(std::ostream& out) 
{ 
    out << "foo"; 
    return out; 
} 

這裏的技巧是,流重載運營商<<這樣,如果你傳遞一個函數指針給它,並且該函數獲取並返回一個流,那麼<<將等同於將該函數應用於流。換句話說,你可以這樣寫:

std::cout << 123 << foo << 456; 

,這將是一樣的:

foo(std::cout << 123) << 456; 

它是如何std::endl實現,例如。

同樣的事情也適用於>>,如果您希望它更通用,您可以在basic_istream和/或basic_ostream上提供模板功能。

+0

謝謝,這是需要的:) – jamieQ 2009-11-11 09:48:35

1

Singleton pattern

您可能也會實現給您的示例模式的一種方式(不是錯誤校驗):

class Global 
{ 
    private: 
    static int counter; 
    Global(){}; 
    static Global *_instance; 

    public: 
    static Global getInstance() { 
    if (!_instance) 
     _instance = new Global(); 
    return *_instance; 
    } 
    friend ostream& operator<<(ostream &out, Global &global); 
} 

Global* Global::_instance = NULL; 

ostream& operator<< (ostream &out, Global &global) 
{ 
    //... do output 
    return out; 
} 

然後調用代碼看起來像:

cout << Global::getInstance() 
+0

Singleton模式可能是最好的主意。無論如何,你需要一個'Global'的實例。 – 2009-11-10 23:58:22

+0

當然,你總是可以使構造函數公開,只是'std :: cout << Global()';但你可能會發現在這裏允許一個公共構造者感到不快。 – 2009-11-10 23:59:01

+0

這會泄漏資源。使用一個簡單的解決方案邁爾單身人士。如果你想使用動態分配,你需要添加at-exit鉤子。 – GManNickG 2009-11-11 00:16:01

0

如果你真的想調用沒有對象實例的函數,你可以這樣做:

std::cout << *(Global*)NULL; 

但是已經提出的單例模式是一個更好的主意。

+0

但是,如果你這樣做,只要確保你的ostream重載靜態訪問成員,如'Global :: counter',而不是通過空引用。 – 2009-11-10 23:56:49