简体   繁体   English

你什么时候为一个类定义ostream运算符<<?

[英]When do you define the ostream operator << for a class?

The question could be subjective, so the syntax of 问题可能是主观的,所以语法是

std::ostream& operator << (std::ostream & o, const SomeClass &a) {
    return o << a.accessor().. ; 
}

When do you normally define this for the classes that you write, when do you avoid writing this friend function for your class. 你通常什么时候为你编写的类定义它,什么时候避免为你的类编写这个友元函数。

IF I want to stream a class I normally write this: 如果我想要流一个类,我通常写这个:

std::ostream& operator << (std::ostream& o, const SomeClass& a)
{
    a.print(o);
    return o; 
}

Then make print a const method on SomeClass that knows how to serialize the class to a stream. 然后在SomeClass上打印一个const方法,该方法知道如何将类序列化为流。

I would only overload operator<< when that has anything to do with streaming, or with shifting and the class is purely numeral. 我只会重载operator <<,当它与流媒体有任何关系时,或者移位时,类是纯粹的数字。 For writing something into an ostream, as in your code, i think it's fine. 对于将某些内容写入ostream,就像在代码中一样,我认为这很好。 Anything else, i think, will cause confusion and i would better use member functions for those other purposes. 我认为,其他任何事情都会引起混淆,我最好将成员函数用于其他目的。 One other application, which i think i would still do as an exception to the rule, is doing something like this: 另一个应用程序,我认为我仍然会作为规则的例外,做这样的事情:

StringList list;
list << "foo" << "bar" << "baz";

It is how Qt does it with its string list, and which i find quite nice. 这是Qt如何使用它的字符串列表,我发现它非常好。

A benefit of Martin's answer above is that you also get polymorphism for free. 马丁上面回答的一个好处是你也可以免费获得多态性。 If you make print(ostream&) a virtual function, then the << operator acts like a virtual function as well! 如果你print(ostream&)一个函数,那么<<操作符就像一个虚函数!

As to when to overload the operator, do so anytime you think the class should be able to be written to a stream (file, socket, etc...). 至于何时重载操作符,只要您认为该类应该能够写入流(文件,套接字等等),就可以这样做。 This might even be only for debug purposes. 这甚至可能仅用于调试目的。 It is often useful to be able to output the internals of a class, so there is no real downside to overloading this operator. 能够输出类的内部结构通常很有用,因此重载此运算符没有真正的缺点。

I would consider using it for something like logging. 我会考虑使用它来记录日志。 So you can do: 所以你可以这样做:

SystemLog systemLog;
systemLog << "Processing Item #15";
systemLog << "Error 0014: Bad things happened.";
systemLog << system.executeCommand(cmd); // returns a result string

Or maybe for networking as in: 或者也许是为了网络:

NetworkInterface networkInterface;
string message("Hello World! I'm a server.");
networkInterface << message;

Of course implementing these things as regular function is also possible and might just be preferable. 当然,将这些东西作为常规功能实现也是可能的,并且可能更好。 Generally, you should beware of operator overloading. 通常,您应该注意运算符重载。 Only use it when it really fits. 只有当它真的适合时才使用它。

I had never ever overloaded this one in production code. 我从来没有在生产代码中重载过这个。 Although you might want do this if you log a lot, it'll be useful. 虽然如果你记录很多,你可能想要这样做,但它会很有用。

I implement this if, and only if, I intend to make use of that operator. 我实现这个,只有当我打算使用该运算符时。 This is pretty much never... my reasons for not implementing it are therefore not using it. 这几乎从未......我没有实现它的理由因此没有使用它。 If its for public use then include it for completeness, but certainly I wouldn't include this in every class in a project of your own, since for the most part you will not need to output a class to a stream. 如果它是公开使用然后包含它是为了完整性,但当然我不会在你自己的项目中的每个类中包含它,因为在大多数情况下你不需要输出类到流。 eg If you wrap your entry point in a class, providing this operator will be pointless. 例如,如果将入口点包装在一个类中,提供此运算符将毫无意义。

我经常这样做,因为它将对象转储到日志以进行调试非常方便。

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

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