【问题标题】:How to properly overload the "<<" operator in C++?如何正确重载 C++ 中的“<<”运算符?
【发布时间】:2016-04-12 04:51:58
【问题描述】:

我想做出像std::cout 这样的行为:

int a = 10, b = 15, c = 7;
MyBaseClass << "a = " << a << ", b = " << b << std::endl;

我尝试实现一些我刚刚读过的东西,但它对我不起作用。我想在我称之为MyBaseClass 的一类中实现operator。我试过这个:

class MyBaseClass {
    private:
        std::ostream someOut;
    public:
        // My first try:
        std::ostream &operator<< ( std::ostream &out, const std::string &message ) {
        }

        // The second try:
        std::ostream &operator<< ( const std::string &message ) {
            someOut << message << std::endl;
            return someOut;
        }

        void writeMyOut() { 
            std::cout << someOut.str() 
        };
};

当我编译这个时,我得到:“调用 'MyBaseClass' 的隐式删除的默认构造函数” - 我需要做什么来修复它?

OS X、Xcode、clang 编译器,都是最新的。

【问题讨论】:

  • 我认为你的第二次尝试应该会奏效,或多或少。编译错误可能是因为MyBaseClass 没有构造函数,但是您需要一个来初始化someOut 成员。 (我不是 100% 确定这是问题所在,但是如果您为 MyBaseClass 提供构造函数,我认为您会走得更远。具体来说,我认为您将获得足够远的时间来尝试在未初始化的std::ostreamsomeOut。)
  • @DaveM。 - 如果我添加一个空的构造函数,我会得到:Field of type 'std::ostream' (aka 'basic_ostream&lt;char&gt;') has protected default constructor
  • @Joel:这个问题不是关于创建一个operator&lt;&lt; 来流式传输用户定义的类型(根据您的重复候选者),而是关于创建一个可以流式传输其他类型的类型。它也可能是重复的,但更难找到。
  • 问题是,你没有初始化std::ostream。我不确定你可以创建一个普通的ostream——你通常要么创建一个ofstream要么创建一个ostringstream(也许现在称为ostrstream?我忘了。)尝试替换std::ostreamstd::ostringstream

标签: c++ operator-overloading


【解决方案1】:

您正试图将多种值类型输出到MyBaseClass 对象中,因此需要支持相同的集合。我还将someOut 更改为std::ostringstream,它能够累积输出。您可能同样希望它是一个 std::ostream&amp; 到传递给构造函数的调用者提供的流......

class MyBaseClass {
    private:
        std::ostringstream someOut;
    public:
        ...other functions...
        // The second try:
        template <typename T>
        MyBaseClass& operator<< ( const T& x ) {
            someOut << x;
            return *this;
        }

        void writeMyOut() const { 
            std::cout << someOut.str() 
        };
};

【讨论】:

  • 在这种情况下我得到:Call to implicitly-deleted default constructor of 'MyBaseClass'
  • @JavaRunner:您自己是否提供了任何MyBaseClass 构造函数(可能是在 DaveM 的提示下)?如果是这样,请删除它们。使用std::ostream&amp; someOut;,您需要MyBaseClass(std::ostream&amp; os) : someOut(os) { },但您不需要为std::ostringstream 指定任何构造函数。
  • 谢谢,您的解决方案很有魅力!这是我的错。
  • @JavaRunner:当然,不用担心。希望你喜欢你的 C++ 编码。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
相关资源
最近更新 更多