简体   繁体   English

重载operator <<作为成员打印

[英]Overloading operator<< for printing as a member

Is there a way to overload the << operator, as a class member, to print values as a text stream. 有没有办法重载<<运算符,作为类成员,将值作为文本流打印。 Such as: 如:

class TestClass {
public:
    ostream& operator<<(ostream& os) {
        return os << "I'm in the class, msg=" << msg << endl;
    }

private:
    string msg;
};


int main(int argc, char** argv) {
    TestClass obj = TestClass();
    cout << obj;

    return 0;
}

The only way I could think of was to overload the operator outside of the class: 我能想到的唯一方法是在类之外重载操作符:

ostream& operator<<(ostream& os, TestClass& obj) {
    return os << "I'm outside of the class and can't access msg" << endl;
}

But then the only way to access the private parts of the object would be to friend the operator function, and I'd rather avoid friends if possible and thus ask you for alternative solutions. 但是,访问对象的私有部分的唯一方法是与操作员函数联系,如果可能的话,我宁愿避开朋友,因此请求您提供替代解决方案。

Any comments or recommendations on how to proceed would be helpful :) 有关如何继续的任何意见或建议将有所帮助:)

It needs to be a non-member, since the class forms the second argument of the operator, not the first. 它必须是非成员,因为类形成运算符的第二个参数,而不是第一个参数。 If the output can be done using only the public interface, then you're done. 如果输出只能使用公共接口完成,那么就完成了。 If it needs access to non-public members, then you'll have to declare it a friend; 如果它需要访问非公开成员,那么你必须声明它是朋友; that's what friends are for. 这就是朋友的作用。

class TestClass {
public:
    friend ostream& operator<<(ostream& os, TestClass const & tc) {
        return os << "I'm a friend of the class, msg=" << tc.msg << endl;
    }

private:
    string msg;
};

You have stumbled across the canonical way to implement this functionality. 您偶然发现了实现此功能的规范方法。 What you have is correct. 你有什么是正确的。

I believe one popular way to do this is a non-member, non-friend free operator<< that calls a public non-virtual print method within your class. 我相信一种流行的方法是使用非成员,非朋友自由operator<<在您的类中调用公共非虚拟print方法。 This print method can either do the work or delegate to a protected virtual implementation. 此打印方法可以执行工作或委托给受保护的虚拟实现。

class TestClass {
public:
    ostream& print(ostream& os) const {
        return os << "I'm in the class, msg=" << msg << endl;
    }

private:
    string msg;
};


ostream& operator<<(ostream& os, TestClass& obj) {
    return obj.print(os);
}

int main(int argc, char** argv) {
    TestClass obj;
    cout << obj;

    return 0;
}

You can make it member of the class, that is on the left of << , which is ostream in your case. 你可以使它成为类的成员,位于<<的左边,在你的情况下是ostream

What you can do, though, is have a base class with void do_stream(ostream& o); 但是,你可以做的是有一个带有void do_stream(ostream& o);的基类void do_stream(ostream& o); member for all your streamables and non-member operator<< that would call it. 所有流量的成员和非会员operator<<会称之为。

You're right, that's the only way to implement the stream operator - outside the class. 你是对的,这是实现流操作符的唯一方法 - 在课外。

You need to declare the method as friend . 您需要将该方法声明为friend

That's how it's done. 这就是它的完成方式。

You have to make it a non member (as the first parameter is not your class). 你必须使它成为非成员(因为第一个参数不是你的类)。

But you can write it inside your class definition (as a friend): 但是你可以把它写在你的类定义中(作为朋友):

class TestClass
{
public:
    // Have a nice friend.
    // This tightly binds this operator to the class.
    // But that is not a problem as in reality it is already tightly bound.
    friend ostream& operator<<(ostream& os, TestClass const& data)
    {
        return os << "I'm in the class, msg=" << data.msg << endl;
    }

private:
    string msg;
};

I see nothing wrong with making this a friend. 我觉得把这个变成朋友是没有错的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM