C++中重载<<运算符:为何返回类型为std::ostream&引用
operator<< return std::ostream& instead of a value? Great question—this is a super common point of confusion when learning to overload stream operators in C++. Let's break down exactly what's going on here.
First: Where does the copy of std::ostream get triggered?
If you tried to return std::ostream by value instead of by reference, the copy happens directly at the return statement. Let's take your example and modify it to use a value return (which will fail to compile):
// This code WILL throw a compile error! std::ostream operator<< (std::ostream &out, const Point &point) { out << "Point(" << point.x << ", " << point.y << ")"; return out; // <-- Attempted copy of `out` happens right here }
When you write return out;, the compiler needs to create a temporary copy of the out object to send back as the function's return value. This requires calling std::ostream's copy constructor—but the standard library explicitly blocks this from happening.
Why does std::ostream prohibit copies?
std::ostream manages low-level resources like output buffers, file handles, or connections to the console. If you could copy an ostream object, you'd end up with two separate objects trying to control the same underlying resource. This leads to total chaos: duplicate writes, double-free errors when the objects are destroyed, or completely corrupted output.
To prevent this mess, the C++ standard makes std::ostream's copy constructor and copy assignment operator deleted (in C++11 and later) or private/unimplemented (in older versions). Any attempt to trigger a copy will immediately throw a clear compile error.
Why returning a reference works
Returning std::ostream& (a reference to the original stream object) avoids all these problems:
- No copy is created—you're just passing a reference to the same
outobject that was passed into the function. - It enables the chained calls we all expect from stream operations. For example:
Eachstd::cout << "First point: " << Point(1,2) << ", second: " << Point(3,4) << std::endl;<<call returns a reference tostd::cout, so the next<<can operate on the exact same stream without any hiccups.
内容的提问来源于stack exchange,提问作者Tom Dara

