收录日期:2019/10/18 22:11:08 时间:2009-11-10 23:41:52 标签:c++,operator-overloading

I have a (simplified) static global class and << operator overload as follows:

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;
}

I want to be able to pass a static reference to cout:

cout << Global

However, the << operator wants an instance, yet no instances of this global class actually exist. Is there anyway around this?

Thanks for any help.

First of all, you cannot use a class name as a value - it simply isn't one. So you'll have to introduce a different name for use with << - say, global (with lowercase "g").

In general, if you want to introduce a "streamable" name without defining an object, you should write a stream manipulator:

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

The trick here is that streams have overloaded operator << such that, if you pass a function pointer to it, and that function takes and returns a stream, then << will be equivalent to applying the function to the stream. In other words, you are able to write:

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

and it'll be the same as:

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

It's how std::endl is implemented, for example.

The same thing also applies to >>, and you can provide template function on basic_istream and/or basic_ostream if you want it to be more generic.

Singleton pattern.

Here's one way you might implement the pattern given your example (not error checked):

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;
}

Then your calling code would look like:

cout << Global::getInstance()

If you really wanted to call such a function with no object instance you could do it like this:

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

But the singleton pattern already suggested is a much better idea.