С++ для начинающих



         

Виртуальный ввод/вывод - часть 4


class AndQuery : public Query {

public:

   virtual ostream& print( ostream &os ) const;

   // ...

};

ostream&

AndQuery::

print( ostream &os ) const

{

   if ( _lparen )

            print_lparen( _lparen, os );

   _lop->print( os );

   os << " && ";

   _rop->print( os );

   if ( _rparen )

            print_rparen( _rparen, os );

   return os;

}

Такая реализация виртуальной функции print() позволяет вывести любой подтип Query в поток класса ostream или любого другого, производного от него:

cout << "Был сформулирован запрос ";

Query *pq = retrieveQuery();

pq->print( cout );

Однако такой возможности недостаточно. Еще нужно уметь распечатывать любой производный от Query тип, который уже есть или может появиться в будущем, с помощью оператора вывода из библиотеки iostream:

Query *pq = retrieveQuery();

cout << "В ответ на запрос "

     << *pq

     << " получены следующие результаты:\n";

Мы не можем непосредственно предоставить виртуальный оператор вывода, поскольку они являются членами класса ostream. Вместо этого мы должны написать косвенную виртуальную функцию:

inline ostream&

operator<<( ostream &os, const Query &q )

{

   // виртуальный вызов print()

   return q.print( os );

}

Строки

AndQuery query;

// сформулировать запрос ...

cout << query << endl;

вызывают наш оператор вывода в ostream, который в свою очередь вызывает

q.print( os )

где q привязано к объекту query класса AndQuery, а os – к cout. Если бы вместо этого мы написали:

NameQuery query2( "Salinger" );

cout << query2 << endl;

то была бы вызвана реализация print() из класса NameQuery. Обращение

Query *pquery = retrieveQuery();

cout << *pquery << endl;

приводит к вызову той функции print(), которая ассоциирована с объектом, адресуемым указателем pquery в данной точке выполнения программы.




Содержание  Назад  Вперед