2009-11-10 6 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:

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

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». –

+0

Конечно, вы всегда можете сделать конструктор общедоступным и просто сделать 'std :: cout << Global()'; но вам может показаться отвратительным разрешить здесь публичный конструктор. –

+0

Это утечка ресурсов. Используйте простой сингл Meyer для простого решения. Если вы хотите использовать динамическое распределение, вам нужно добавить at-exit hooks. – GManNickG

0

Если вы действительно хотел вызовите такую ​​функцию без экземпляра объекта, вы можете сделать это следующим образом:

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

Но уже предложенный одноэлементный шаблон является гораздо лучшей идеей.

+0

Но если вы это сделаете, убедитесь, что ваша перегрузка ostream получает доступ к элементам статически, например, «Global :: counter», а не через нулевую ссылку. –

Смежные вопросы