【问题标题】:Custom ostream prints only last string of `<<` chain自定义 ostream 仅打印 `<<` 链的最后一个字符串
【发布时间】:2016-07-13 07:09:02
【问题描述】:

我正在尝试使用自定义流运算符实现一个类,并从它继承,以便拥有一个基类和一个具有不同流的派生类。然后我重载&lt;&lt; 运算符以使用存储的ostream

这是代码的工作示例:

#include <string>
#include <memory>
#include <ostream>
#include <iostream>#
#include <fstream>

class Sink {
public:
    Sink() {
        m_stream = std::unique_ptr<std::ostream>(new std::ostream(std::cout.rdbuf()));
    };

    template<typename T>
    std::ostream& operator<<(const T& obj) {
        return *m_stream;
    }

protected:

    std::unique_ptr<std::ostream> m_stream;
};

class FileSink : public Sink {
public:

    FileSink() {
        m_stream = std::unique_ptr<std::ostream>(new std::ofstream("file.txt"));
    }
};

int main() {
    Sink s;
    FileSink fs;
    s << "First console string " << "second console string";
    fs << "First file string " << "second file string";
    return 0;
}

Sink class 我写在控制台上,FileSink 写在一个文件上。

问题在于,使用这段代码我只打印每条指令的最后一个字符串。

在控制台中我看到以下输出:

second console string

在文件中我可以看到这个输出:

second file string

我做错了什么以及如何打印预期的输出?

【问题讨论】:

  • 滥用 std::unique_ptr 的一个很好的例子(一个简单的指针就在这里)
  • @DieterLücking 什么是原始指针优势?
  • @DieterLücking 如果 Sink 类拥有指针,为什么不使用 unique_ptr?否则,您需要一个自定义的复制或移动构造函数和一个析构函数
  • .... 这就是滥用:sink 不拥有任何东西。

标签: c++ ofstream ostream


【解决方案1】:

你的operator&lt;&lt; 什么都不做,返回std::ostream&amp;。然后你将std::ostream::operator&lt;&lt; 应用到那个std::ostream&amp;。意料之中!

做你想做的事的标准方法:

template<typename T>
Sink & Sink::operator<<(const T& obj) {
    *m_stream << obj;
    return *this;
}
template<typename T>
FileSink & FileSink::operator<<(const T& obj) {
    *m_stream << obj;
    return *this;
}

为了防止代码重复,您可以使用继承。我认为它可能会重复std::stream 继承方案。 :)

【讨论】:

    【解决方案2】:
    template<typename T>
    std::ostream& operator<<(const T& obj) {
        *m_stream << obj;    // you missed this
        return *m_stream;
    }
    

    此外,您可以将 operator

    template <typename T> 
    Sink& operator<<(Sink &sink, const T &obj) {
        *(sink.m_stream) << obj;
        return sink;
    }
    

    让它成为 Sink 的朋友:

    class Sink {
        template <typename T>
        friend Sink& operator<<(Sink &sink, const T &obj);
        // other code.
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-20
      • 2021-07-03
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 2021-05-11
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      相关资源
      最近更新 更多