为什么我们需要在重载时返回对 istream/ostream 的引用 >>并且<<运营商?
如果我不返回 din
或 dout
会发生什么,实际上我正在读一本书,其中作者返回了流引用
What happens if I do not return din
or dout
, actually I'm reading a book in which writer returns back stream references
istream & operator>>(istream &din,vector &a)
{
for(int i=0;i<size;i++)
din>>a.v[i];
return din;
}
ostream & operator<<(ostream &dout,vector &a)
{
dout<<"("<<a.v[0];
for(int i=1;i<size;i++)
dout<<", "<<a.v[i];
dout<<")";
return dout;
}
推荐答案
原因是几个事实的结合.
The reason is a combination of several facts.
您希望能够像这样链接输入和输出操作
You want to be able to chain input and output operations as in
in >> x >> y;
out << z << std::precision(10) << t << std::endl;
所以你必须返回一些允许 operator<<
的东西.
so you must return something that allows operator<<
again.
由于您希望操作符处理任何 istream
,即从 std::istream
派生的任何对象,您不能定义
Since you want your operator to work on any istream
, i.e. any object derived from std::istream
, you cannot define
operator<<(istream_type, object); // take istream by value
因为这仅适用于特定的 istream 类型 istream_type
,而不适用于通用的 istream
.为此,必须使用多态性,即采用引用或指针(将是指向从 std::istream
派生的类的引用或指针).
since this would only work for the specific istream type istream_type
, but not for a generic istream
. For that one must use polymorphism, i.e. either take a reference or a pointer (which will be a reference or pointer to a class derived from std::istream
).
由于您只有对 istream 的引用,因此您无法返回 istream 对象本身(其类型可能在 operator<<
) 但只有你得到的参考.
Since you only have a reference to the istream, you cannot return the istream object itself (which may be of a type not even defined at the point of the definition of operator<<
) but only the reference you've got.
可以通过定义 operator<<
一个 template
并按值获取并返回 istream_type
来绕过此限制,但这需要istream
类型有一个复制构造函数,它很可能没有充分的理由.
One could get around this restriction by defining operator<<
a template
and take and return the istream_type
by value, but that requires the istream
type to have a copy constructor, which it may well not have for good reasons.
为了激发多态性,原则上可以使用指针(指向流)而不是引用.但是,operator<<(stream*,const char*)
是在 C++ 中不允许(至少一个操作数必须是类或枚举类型).
In order to envoke polymorphism one could, in principle, use pointers (to streams) rather than references. However, operator<<(stream*,const char*)
is
not allowed in C++ (at least one operand must be of class or enumeration type).
因此,对于流指针,必须使用函数调用语法,而您又回到了 C 风格的fprintf(stream*, args...)
.
Thus, with stream pointers one must use function-call syntax and you're back with C-style fprintf(stream*, args...)
.
此外,指针可以为空或悬空,这实际上是它们的默认状态(在没有初始化器的情况下声明时),而可以假定引用是有效的(没有初始化器就不能声明).
Moreover, pointers can be null or dangling, which in fact is their default state (when declared without initializer), while a reference can be assumed to be valid (it cannot be declared without initializer).
相关文章