Как передать объекты ostream?

у меня есть такая структура

struct X{
    ostream out;
    X() : out(cout) {}
    ...
};

и я заметил, что я должен определить out с помощью &, чтобы правильно передать cout как параметр по умолчанию: ostream Я не знаю, почему, и я не знаю, есть ли другие возможности сохранить ostream без &. Кроме того, когда я пытаюсь установить

X x;
ofstream out;
x.out = out;

компилятор обнаружил много ошибок... Я хочу установить X::out в cout или в поток. Как это сделать?


person bluePhlavio    schedule 31.05.2014    source источник
comment
ostream по сути является абстрактным базовым классом, который, кроме того, не копируется (но перемещается).   -  person Kerrek SB    schedule 31.05.2014


Ответы (3)


ostreams нельзя передавать по значению. Вы должны пройти по ссылке или указателю.

Если вы хотите, чтобы x.out ссылался на разные потоки во время своего существования, сделайте его указателем. В противном случае сделайте ссылку.

person M.M    schedule 31.05.2014
comment
Интересно, почему. Можно было бы реализовать семантику копирования и присваивания, аналогичную shared_ptr, не так ли? т.е. все копии ссылаются на один и тот же fd и совместно используют один буфер, если только они не переназначены. - person Peter - Reinstate Monica; 31.05.2014
comment
@PeterSchneider: Ну, вы всегда можете просто сделать std::shared_ptr<std::ostream> (у которого есть те же проблемы, что и у потокового класса, выполняющего это напрямую) - person Christian Hackl; 31.05.2014

Лучшее, что вы можете сделать, это изменить дизайн вашего класса, чтобы вам больше не нужно было инициализировать переменную-член. Копирование предотвращается компилятором, решения, основанные на указателях, приведут к проблемам с владением, std::shared_ptr создает проблемы с std::cout, а элемент ссылки создаст возможность висячих ссылок.

Попробуйте реорганизовать свой код так, чтобы поток всегда передавался как ссылка на методы извне, когда это необходимо:

struct X{
    X() {}
    void f(std::ostream &os);
};
person Christian Hackl    schedule 31.05.2014

Объект потока нельзя скопировать, вам нужно использовать ссылку.

struct X{
    ostream& out;

     X() :out( std::cout ) {}

     // X( ostream& out_ = std::cout ) : out( out_ ) {}

}; 
person P0W    schedule 31.05.2014