Lo que yo recomendaría hacer es tener una clase que se envuelve alrededor de un iostream como esto:
#include <iostream>
#define LOG Log()
class Log
{
public:
Log(){}
~Log()
{
// Add an newline.
std::cout << std::endl;
}
template<typename T>
Log &operator << (const T &t)
{
std::cout << t;
return * this;
}
};
Entonces, cada vez que desee cambiar el lugar donde van los datos, sólo cambia el comportamiento de la clase. Aquí es cómo se utiliza la clase:
LOG << "Use this like an iostream.";
[editar] Como sugirió matamoscas papa, voy a añadir un ejemplo de algo que no sea cout:
#include <sstream>
#define LOG Log()
// An example with a string stream.
class Log
{
private:
static std::stringstream buf;
public:
Log(){}
~Log()
{
// Add an newline.
buf << std::endl;
}
template<typename T>
Log &operator << (const T &t)
{
buf << t;
return * this;
}
};
// Define the static member, somewhere in an implementation file.
std::stringstream Log::buf;
cuanto a por qué usted debe tratar esto en lugar de heredar de algo así como un flujo de cadena, principalmente porque puedes cambiar fácilmente a donde el Logger saca dinámicamente. Por ejemplo, usted podría tener tres corrientes de salida diferentes, y utilizar una variable miembro estática de cambiar entre en tiempo de ejecución:
class Log
{
private:
static int outputIndex = 0;
// Add a few static streams in here.
static std::stringstream bufOne;
static std::stringstream bufTwo;
static std::stringstream bufThree;
public:
// Constructor/ destructor goes here.
template<typename T>
Log &operator << (const T &t)
{
// Switch between different outputs.
switch (outputIndex)
{
case 1:
bufOne << t;
break;
case 2:
bufTwo << t;
case 3:
bufThree << t;
default:
std::cout << t;
break;
}
return * this;
}
static void setOutputIndex(int _outputIndex)
{
outputIndex = _outputIndex;
}
};
// In use
LOG << "Print to stream 1";
Log::setOutputIndex(2);
LOG << "Print to stream 2";
Log::setOutputIndex(3);
LOG << "Print to stream 3";
Log::setOutputIndex(0);
LOG << "Print to cout";
Esto puede ampliar fácilmente para crear una poderosa manera de hacer frente a la tala. Se podría añadir FileStreams, utiliza std :: cerr, etc.
C++ no tiene "formas". –
Ok, me refiero a algo visual, no a la consola – Bakudan
Tenga en cuenta que, por lo general, la anulación del comportamiento de las secuencias se realiza mediante la implementación de la interfaz std :: streambuf. Esa es una tarea bastante compleja, por lo que probablemente debería usar otras respuestas proporcionadas. – Basilevs