friend ostream &operator<<( ostream&, Complex& );
为什么我不能使用
friend ostream operator<<( ostream&, Complex&);
答案 0 :(得分:2)
它没有必须,但有几个原因可以解释为什么这是一个常见的选择。
处理流的许多STL类和对象通常选择返回引用,因为这允许链接
class MyClass {
public:
MyClass(int v) : value(v) {}
int value;
friend MyClass &operator<<( MyClass&, MyClass& );
};
MyClass &operator<< (MyClass& a, MyClass& b) {
a.value += b.value;
return a;
}
int main() {
MyClass a(2);
MyClass b(3);
MyClass c(5);
a << b << c; // Chaining
std::cout << a.value; // 10
}
如果按价值返回,则无法在一行中完成
a << b; // Can't chain
a << c;
关于上述类别的另一个重要原因是,处理流意味着您无法复制流(https://stackoverflow.com/a/6010930/1938163),因为它并不完全有道理。
这也意味着如果您将流对象保留在对象的状态(您将获得一个隐式删除的复制构造函数),则无法按值返回
class MyClass {
public:
MyClass(std::string str) {
ss << str;
}
std::stringstream ss; // This CANNOT be copied
friend MyClass operator<<( MyClass&, MyClass& );
};
MyClass operator<< (MyClass& a, MyClass& b) {
a.ss << b.ss.str();
return a; // Can't do this! Copy ctor is implicitly deleted due to ss
}
在后者中,通过引用返回的常见情况几乎是必须的。
除了这些案件之外,没有人强迫你通过引用返回。它还取决于您的用例,更重要的是,关于您的对象如何管理其资源(请记住,如果按值返回,如果没有{{3>则可能会涉及析构函数参与)。
答案 1 :(得分:1)
按值返回意味着需要复制对象,否则它可能无效,因为原始(复制源)对象在调用析构函数后可能会自行清理,因此对于流可能会产生问题。通过引用返回可以避免这种情况,更重要的是,链接的调用将在每次ostream
调用后共享相同的<<
而不是新的流。
答案 2 :(得分:1)
std::ostream
明确阻止了您复制它的能力。请注意,它有一个已删除的复制构造函数。
因此,如果您尝试按值返回它,则会导致编译器错误。
答案 3 :(得分:0)
这不是一个严格的要求。如果您使用非参考版本,
ostream << a << b << c
将为运算符的每次调用复制ostream对象&lt;&lt;什么时候回来。您可能没有理由想要复制而不是原始的ostream对象。