I have a c++ library that provides an object with complicated logic. During data processing, this object outputs lots of things to std::cout (this is hardcoded now). I would like the processing output not to go to standard output but to a custm widget (some text displaying). I tried to create a std::ostream
class member, set it with a parameter (std::cout for console application and some other ostream handled inside GUI application). But the compiler throws me following errors:
[ 14%] Building CXX object src/core/CMakeFiles/PietCore.dir/pvirtualmachine.cpp.o /usr/include/c++/4.6/ostream: In constructor ‘PVirtualMachine::PVirtualMachine(QString)’: /usr/include/c++/4.6/ostream:363:7: error: ‘std::basic_ostream::basic_ostream() [with _CharT = char, _Traits = std::char_traits]’ is protected /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.cpp:33:50: error: within this context In file included from /usr/include/c++/4.6/ios:45:0, from /usr/include/c++/4.6/ostream:40, from /usr/include/c++/4.6/iterator:64, from /usr/include/qt4/QtCore/qlist.h:50, from /usr/include/qt4/QtCore/qvector.h:48, from /usr/include/qt4/QtGui/qpolygon.h:45, from /usr/include/qt4/QtGui/qmatrix.h:45, from /usr/include/qt4/QtGui/qtransform.h:44, from /usr/include/qt4/QtGui/qimage.h:45, from /usr/include/qt4/QtGui/QImage:1, from /home/tomasz/Development/C++/piet/src/core/pcodepointer.h:17, from /home/tomasz/Development/C++/piet/src/core/pblockmanager.h:9, from /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.h:10, from /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.cpp:4: /usr/include/c++/4.6/bits/ios_base.h: In member function ‘std::basic_ios& std::basic_ios::operator=(const std::basic_ios&)’: /usr/include/c++/4.6/bits/ios_base.h:791:5: error: ‘std::ios_base& std::ios_base::operator=(const std::ios_base&)’ is private /usr/include/c++/4.6/bits/basic_ios.h:64:11: error: within this context In file included from /usr/include/c++/4.6/iterator:64:0, from /usr/include/qt4/QtCore/qlist.h:50, from /usr/include/qt4/QtCore/qvector.h:48, from /usr/include/qt4/QtGui/qpolygon.h:45, from /usr/include/qt4/QtGui/qmatrix.h:45, from /usr/include/qt4/QtGui/qtransform.h:44, from /usr/include/qt4/QtGui/qimage.h:45, from /usr/include/qt4/QtGui/QImage:1, from /home/tomasz/Development/C++/piet/src/core/pcodepointer.h:17, from /home/tomasz/Development/C++/piet/src/core/pblockmanager.h:9, from /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.h:10, from /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.cpp:4: /usr/include/c++/4.6/ostream: In member function ‘std::basic_ostream& std::basic_ostream::operator=(const std::basic_ostream&)’: /usr/include/c++/4.6/ostream:57:11: note: synthesized method ‘std::basic_ios& std::basic_ios::operator=(const std::basic_ios&)’ first required here /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.cpp: In member function ‘void PVirtualMachine::setOutput(std::ostream)’: /home/tomasz/Development/C++/piet/src/core/pvirtualmachine.cpp:216:11: note: synthesized method ‘std::basic_ostream& std::basic_ostream::operator=(const std::basic_ostream&)’ first required here
I'd be glad if someone pointed me out what is wrong, because I've got no idea...
My code looks like this:
class PVirtualMachine { private: std::ostream output; [...] public: void setOutput(std::ostream); [...] };
void PVirtualMachine::setOutput(std::ostream os) { output = os; }
You've got two options here:
You can't use normal instances because ostream
is non-copyable.
Using references (direct reference to an already-instantiated ostream
)
class PVirtualMachine {
private:
std::ostream & output;
[...]
public:
PVirtualMachine(std::ostream &); // Reference must be initialized on construction.
[...]
};
Advantages:
std::ostream
, as long as the original variable is not deleted.Disadvantages:
PVirtualMachine
class must be constructed with the output reference in the initialization list, otherwise it will not compile.operator=(PVirtualMachine &&)
)Using pointers (optional reference to object)
class PVirtualMachine {
private:
std::ostream * output;
[...]
public:
void setOutput(std::ostream *);
[...]
};
Advantages:
std::ostream
instance.Disadvantages:
You can use a reference to a std::ostream
instead, this would support any kind of output stream, e.g. stdout, file, etc. This is fine as long as you only want to use one single stream, and the stream doesn't get destroyed:
class PVirtualMachine {
private:
std::ostream & output;
[...]
public:
PVirtualMachine(std::ostream & os = std::cout): output(os) { }
// void setOutput(std::ostream & os) { output = os; } // can't change the reference
[...]
};
If you want this class to share the stream (therefore keeping it alive for this class's lifetime), use a std::shared_ptr<std::ostream>
instead of a reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With