2009-11-10 93 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