У меня есть три класса: ConsoleInputStream
, ConsoleOutputStream
, ConsoleErrorStream
. Все они получены от Stream
.C++ extern: указатель против ссылки
Каждый поток имеет виртуальные функции read
и write
; как вы предполагаете, когда пользователь пытается использовать функцию-член ConsoleInputStream
write
, он выдает сообщение об ошибке. То же самое происходит, когда пользователь пытается использовать функцию ConsoleOutputStream
write
.
Теперь пришло время показать код.
// STREAM.HPP
namespace streamlib {
extern ConsoleInputStream stdin_default;
extern ConsoleOutputStream stdout_default;
extern ConsoleErrorStream stderr_default;
extern Stream& stdin;
extern Stream& stdout;
extern Stream& stderr;
} // namespace streamlib
// STREAM.CPP
namespace streamlib {
ConsoleInputStream stdin_default;
ConsoleOutputStream stdout_default;
ConsoleErrorStream stderr_default;
Stream& stdin = stdin_default;
Stream& stdout = stdout_default;
Stream& stderr = stderr_default;
} // namespace streamlib
// MAIN.CPP
int main()
{
streamlib::stdout = streamlib::stdin;
streamlib::stdout.write(); // Still working, but should have thrown error!
}
Однако, все работает отлично, когда я определяю stdin
, stdout
и stderr
как указатели вместо ссылки, то есть ошибка возникает, как ожидалось. Но я не хочу выделять/освобождать память и использовать оператор ->
, где я мог бы (мог бы?) Использовать оператор простой точки.
Реальная ситуация, конечно, еще более intricated: У меня также есть некоторые другие виды, полученные из Stream
и просто хочу, чтобы иметь возможность быстро перегрузить stdin
, stdout
, stderr
потоков с различными видами потоков. Можно ли это сделать со ссылками?
Заранее благодарен!
(Я игнорирую очевидные опечатки в стороне заголовка/.cpp, где вы явно смешали stdout/stdout_default) Не уверен, что именно вы ищете. Я думаю, проблема в том, что вы пытаетесь присвоить один поток другому, и это само по себе, вероятно, плохое (в более крупной схеме вы теперь «просочились» ссылку на основной дескриптор файла или что-то в этом роде). Если это проблема, то отказ от всех присвоений одного потока другому, вероятно, имеет смысл. Вы можете использовать 'private: operator = (Stream &)', чтобы запретить его. –
@MatsPetersson: Я исправил опечатки. Могли бы вы посоветовать лучший способ перенаправить такие потоки? Я думал об использовании функций-членов 'int fd() const' и' void fd (int) 'для изменения дескриптора файла внутри экземпляра класса, но это явно не охватывает некоторые ситуации, скажем, если я попытаюсь перенаправить на виртуальный поток (что-то вроде std :: ostringstream), который не имеет файлового дескриптора. – ghostmansd
Я не уверен, что понимаю, о чем вы спрашиваете, какова была цель перенаправления выходного файла в качестве входного файла? –