我如何用两种方式输出 <<?

问题描述 投票:0回答:3

例如,如果我想要一个带有

<<
的默认输出版本和详细版本。

myClass myObject(//Constructor parameters);

cout << myObject << "\n";
cout << myObject.detailed << "\n";

我尝试在我的班级中制作一个修饰符,但这似乎不起作用。

class myClass {
public:
   friend std::ostream& operator<<(std::ostream& output, const myClass& myObject);
   std::ostream& detailed(std::ostream& output);
}

这给出了错误“必须调用对非静态成员函数的引用”。

c++ operator-overloading ostream
3个回答
5
投票

这是根据 iostreams 设计应该如何完成的。

#include <iostream>

class MyClass
{
    static const int flagId; // private format flag
  public:
    int x, y; // for exposition only
    static std::ios_base& detailed(std::ios_base& str) {
        str.iword(flagId) = true;
        return str;
    }
    static std::ios_base& abridged(std::ios_base& str) {
        str.iword(flagId) = false;
        return str;
    }

    friend std::ostream& operator<< (std::ostream& stream, const MyClass& myClassObj) {
        if (stream.iword(flagId)) {
            stream << "X=" << myClassObj.x << " Y=" << myClassObj.y;
            // optionally reset the flag to false
        } else {
            stream << myClassObj.x;
        }
        return stream;
    }
};

const int MyClass::flagId = std::ios_base::xalloc();

int main()
{
    MyClass myObject{1, 42};
    std::cout << MyClass::detailed << myObject << "\n";
    std::cout << MyClass::abridged << myObject << "\n";
}

2
投票

您无法将非静态类方法传递给

operator<<
,它不支持调用该方法的能力,因此会出现错误。

对于您尝试执行的操作,您需要将

detailed
更改为 stream manipulator 对象而不是成员函数,例如:

struct detailed {
    const myClass &cls;
    detailed(const myClass &cls) : cls(cls) {} 
    friend std::ostream& operator<<(std::ostream& os, const detailed& det) {
        // print details about det.cls as needed...
        return os;
    }
};


myClass myObject(...);

cout << detailed(myObject) << "\n";

例如,这就是

std::(re)setiosflags
std::set(base|fill|precision|w)
std::quoted
等标准参数操纵器的实现方式。


0
投票

我认为我的方法与@RemyLebeau 相同,但更通用。

#include <iostream>
#include <string>

//---------------------------------------------------------------------------------------------
// class templated to be able to apply
// detailed mechanism to different types

template<typename type_t>
class detailed
{
public:
    detailed(const type_t& object) : 
        m_object{ object } 
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const detailed<type_t>& detailed_object)
    {
        detailed_object.m_object.detailed_output(os);
        return os;
    }

private:
    const type_t& m_object;
};

//---------------------------------------------------------------------------------------------
// like your class

struct test_class_t
{
public:
    friend std::ostream& operator<<(std::ostream& os, const test_class_t& object)
    {
        os << object.basic;
        return os;
    }

    void detailed_output(std::ostream& os) const // <- const is important
    {
        os << basic << ", " << details;
    }

private:
    std::string basic{ "basic" };
    std::string details{ "details" };
};

//---------------------------------------------------------------------------------------------

int main()
{
    test_class_t object;
    std::cout << detailed{object} << "\n";
}
© www.soinside.com 2019 - 2024. All rights reserved.