覆盖c ++流

Bak*_*dan 8 c++ overriding

在C++程序中,我们有3个数据流:stdin,stdout,和stderr.我可以在控制台应用程序中覆盖它们并在使用表单的应用程序中使用它们吗?

例如,如果在某些基类中,我cout<< "..."可以"重定向"到可视化的东西(如Windows窗体)吗?

Dar*_*ner 10

我建议做的是有一个类包围这样的iostream:

#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;
      }
};
Run Code Online (Sandbox Code Playgroud)

然后,每当您想要更改数据的位置时,您只需更改类行为即可.以下是您使用该类的方法:

 LOG << "Use this like an iostream.";
Run Code Online (Sandbox Code Playgroud)

[编辑]正如马铃薯拍建议的那样,我将添加一个除了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;
Run Code Online (Sandbox Code Playgroud)

至于为什么你应该尝试这个而不是继承像字符串流这样的东西,主要是因为你可以很容易地动态改变Logger输出的位置.例如,您可以有三个不同的输出流,并使用静态成员变量在运行时交换:

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";
Run Code Online (Sandbox Code Playgroud)

这可以很容易地扩展,以创建一种处理日志记录的强大方法.你可以添加文件流,使用std :: cerr等.

  • 这基本上是从头开始。例如,如果现有代码使用格式操纵器或 `endl` 怎么办?此外,这个例子没有说明如何与除 `cout` 之外的东西交互。 (2认同)