una tramites tiempo testamento tarda requisitos reparte recibir que procedimiento para necesitan legal hermanos herencia form entre ejercicios documentos cuanto como cobrar inheritance stl ostream

inheritance - tramites - Cómo heredar de std:: ostream?



requisitos para cobrar una herencia (5)

Composición, no herencia. Su clase contiene, "envuelve" un ostream &, y lo reenvía (después de llamar a foo ()).

He estado buscando en Google y simplemente no puedo encontrar una respuesta simple para esto. Y debería ser simple, como generalmente lo es STL.

Quiero definir MyOStream que hereda públicamente de std :: ostream. Digamos que quiero llamar a foo () cada vez que se escribe algo en mi transmisión.

class MyOStream : public ostream { public: ... private: void foo() { ... } }

Entiendo que la interfaz pública de ostream no es virtual, ¿cómo se puede hacer? Quiero que los clientes puedan usar el operador << y write () y put () en MyOStream y que utilicen la capacidad extendida de mi clase.


Estaba dando vueltas sobre cómo hacer lo mismo y descubrí que en realidad no es tan difícil. Básicamente solo subclase los objetos ostream y streambuf, y construya el ostream consigo mismo como el buffer. se utilizará el desbordamiento virtual () de std :: streambuf para cada carácter enviado a la transmisión. Para adaptarse a su ejemplo, acabo de hacer una función foo () y la llamé.

struct Bar : std::ostream, std::streambuf { Bar() : std::ostream(this) {} int overflow(int c) { foo(c); return 0; } void foo(char c) { std::cout.put(c); } }; void main() { Bar b; b<<"Look a number: "<<std::hex<<29<<std::endl; }

oh e ignora el hecho de que la función principal no es una función principal real. Está en un espacio de nombres llamado desde otro lugar; p


No es una pregunta simple, desafortunadamente. Las clases de las que deberías derivar son basic_ classes, como basic_ostream . Sin embargo, la derivación de una secuencia puede no ser la que desea, puede que desee derivar de una memoria intermedia de secuencia en su lugar, y luego utilizar esta clase para crear una instancia de una clase de secuencia existente.

Toda el área es compleja, pero hay un excelente libro sobre el estándar C ++ IOStreams y Locales , que sugiero que le echen un vistazo antes de seguir adelante.


No sé si esta es la solución correcta, pero heredé de std :: ostream de esta manera. Utiliza un búfer heredado de std :: basic_streambuf y obtiene 64 caracteres a la vez (o menos si se vació) y los envía a un método putChars () genérico donde se realiza el manejo real de los datos. También demuestra cómo dar datos de usuario.

Ejemplo en vivo

#include <streambuf> #include <ostream> #include <iostream> //#define DEBUG class MyData { //example data class, not used }; class MyBuffer : public std::basic_streambuf<char, std::char_traits<char> > { public: inline MyBuffer(MyData data) : data(data) { setp(buf, buf + BUF_SIZE); } protected: // This is called when buffer becomes full. If // buffer is not used, then this is called every // time when characters are put to stream. inline virtual int overflow(int c = Traits::eof()) { #ifdef DEBUG std::cout << "(over)"; #endif // Handle output putChars(pbase(), pptr()); if (c != Traits::eof()) { char c2 = c; // Handle the one character that didn''t fit to buffer putChars(&c2, &c2 + 1); } // This tells that buffer is empty again setp(buf, buf + BUF_SIZE); return c; } // This function is called when stream is flushed, // for example when std::endl is put to stream. inline virtual int sync(void) { // Handle output putChars(pbase(), pptr()); // This tells that buffer is empty again setp(buf, buf + BUF_SIZE); return 0; } private: // For EOF detection typedef std::char_traits<char> Traits; // Work in buffer mode. It is also possible to work without buffer. static const size_t BUF_SIZE = 64; char buf[BUF_SIZE]; // This is the example userdata MyData data; // In this function, the characters are parsed. inline void putChars(const char* begin, const char* end){ #ifdef DEBUG std::cout << "(putChars(" << static_cast<const void*>(begin) << "," << static_cast<const void*>(end) << "))"; #endif //just print to stdout for now for (const char* c = begin; c < end; c++){ std::cout << *c; } } }; class MyOStream : public std::basic_ostream< char, std::char_traits< char > > { public: inline MyOStream(MyData data) : std::basic_ostream< char, std::char_traits< char > >(&buf), buf(data) { } private: MyBuffer buf; }; int main(void) { MyData data; MyOStream o(data); for (int i = 0; i < 8; i++) o << "hello world! "; o << std::endl; return 0; }


Otro truco de trabajo para lograr un efecto similar es usar plantilla y composición

class LoggedStream { public: LoggedStream(ostream& _out):out(_out){} template<typename T> const LoggedStream& operator<<(const T& v) const {log();out << v;return *this;} protected: virtual void log() = 0; ostream& out; }; class Logger : LoggedStream { void log() { std::cerr << "Printing" << std::endl;} }; int main(int,char**) {LoggedStream(std::cout) << "log" << "Three" << "times";}