覆盖c ++流 [英] Override c++ streams

查看:134
本文介绍了覆盖c ++流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++程式中,我们有3个资料流: stdin stdout stderr 。来自控制台应用程序的代码可以覆盖并在表单应用程序中使用吗?

In C++ program we have 3 streams stdin, stdout and stderr. Can a code from console application, be overrided and used in form application?

例如,如果在一些基类中有 cout< ...这可以重定向到形式(编辑:除了控制台之外的视觉效果)或某物。

For example if in some base class I have cout<< "..." this can be "redirected" to form ( edit: something visual other than console ) or something.

推荐答案

我建议做一个类包装一个iostream像这样:

What I would recommend doing is having a class which wraps around an iostream like this :

#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;
      }
};

然后,每当你想改变数据的来源,你只需要改变类的行为。
下面是如何使用类:

Then, whenever you want to change where the data goes, you just change the class behavior. Here is how you use the class:

 LOG << "Use this like an iostream.";


我建议使用土豆,比cout:

[edit] As potato swatter suggested, I'll add an example with something other than 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;

至于为什么你应该尝试这个,而不是继承自一个字符串流,主要是因为你可以轻松地改变Logger输出到动态的位置。例如,您可以有三个不同的输出流,并使用静态成员变量在运行时切换:

As for why you should try this instead of inheriting from something like a string stream, mainly because you can easily change where the Logger outputs to dynamically. For instance, you could have three different output streams, and use a static member variable to swap between at runtime:

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";

这可以轻松扩展,创建一个强大的处理日志记录的方法。您可以添加filestreams,使用std :: cerr等。

This can easily be expanded to create a powerful way of dealing with logging. You could add filestreams, use std::cerr, etc.

这篇关于覆盖c ++流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆