关于cin / cout重载的简单问题

时间:2010-07-16 22:22:46

标签: c++

我知道这是非常基本的,但我有点猜测到这一点。

Foo只是一个具有来自字符串类的私有继承的对象,这就是我投射它的原因。使用Primer C ++(Prata's)中的示例

所以,如果我有这样的功能:

istream & operator>>(istream & is, Foo & f)
{
      is >> (string &)f;
      return is;
}

int main()
{

Foo f;


cin >> f; 

}

所以,一旦cin>> f被命中,函数被调用,而now字符串存储在istream引用中。 istream对象现在返回,现在......?返回的istream对象的内容(字符串)现在是否自动放在f中?或者我是否错过了解cin如何工作的一步?

另外,如果我这样做:

int x;

cin >> f >> x;

它会如何隐含的样子?喜欢(cin)>> X?

最后,还有一件简单的事情。如果在一个函数(包含一个ostream引用)中,我在循环遍历每个数组项并执行此操作:

for(int i=0;i < 5;i++)
{
os << array[i] << "\n";
}

ostream对象是否只是复合了每个数组项?

4 个答案:

答案 0 :(得分:3)

如果使用普通函数调用替换重载运算符,则变得非常容易。 cin >> f只是转换为:

operator >>(cin, f);

现在将cin >> f >> x视为(cin >> f) >> x。这转化为:

operator >>(operator >>(cin, f), x);

由于第一个运算符返回cin,因此在执行期间,它实际上变为:

operator >>(cin, x);

原始数据类型(如int)通常在流类本身内重载,因此它实际上如下所示:

cin.operator >>(x);

您可以自行解决此问题,以回答有关ostream的问题 - 它的工作原理完全相同。

答案 1 :(得分:1)

执行cin >> f时,重载决策会选择重载的istream >>重载并调用它。然后,在您的重载中,您从流中提取string,该流调用带有istream和>>的{​​{1}}重载。

请注意,从string派生出来是非常不寻常的,甚至是私下的。相反,您应该使用组合:拥有类型为std::string的成员变量。

你的演员阵容很混乱;如果你有一个std::string类型的成员变量,那么你可以使用更自然的语法来提取它:

std::string

is >> f.stringmembervariable; 首先从cin >> f >> x中提取Foo并将其存储在cin中,然后从f中提取int并将其存储在cinx。假设所有>>重载遵循返回它们被传递的istream的约定,它实际上就像你说的那样:

cin >> f;
cin >> x;

这就是你应该从>>重载返回istream的原因,这样就可以像这样链接提取。

至于你的上一个问题,在循环内部,无论<<的类型是什么,都会调用重载的ostream array[i]运算符。

答案 2 :(得分:1)

istream & operator>>(istream & is, Foo & f)
{
      is >> (string &)f;
      return is;
}

istream& operator>>(istream& is, string& f)(好吧,basic_istream<T>&, basic_sttring<T>&)已经存在。所以,虽然你可以这样做,但为什么呢?

  

所以,一旦cin&gt;&gt; f被命中,函数被调用,而now字符串存储在istream引用

不,流被istream& operator>>(istream& is, string& f)消耗,它将字符串(的存储空间)设置为包含消耗字节的表示。

然后返回对istream的引用。

int x;
cin >> f >> x;

相当于:

int x;
(cin >> f) >> x;

因为操作员关联规则,并且“真的”:

int x;
std::operator>>( ::operator>>(cin,  f), x ) ;

其中两个operator>>op>>的两个不同的重载版本,也就是说,你的版本(在全局命名空间中)采用了一个istream和一个Foo是内部的一个,返回对istream的引用,在转向中是外部的第一个参数,std命名空间中的一个带有istream和int。

  

ostream对象是否只是复合了每个数组项?

每个对象,无论array [n]是什么类型,都会被添加到ostream, in sequence ,添加到流中,后跟换行符。所以“compunded”是表达它的坏方法,但是是的。当然,需要存在op<<( ostream&, const X&),其中“X”是数组[n]的任何类型(或者可以隐式转换为)。

答案 3 :(得分:0)

当你这样做时:

cin >> f;

你是正确的,你的操作员函数将被调用,而cin上的任何字符串现在都将存储在f中。

当你这样做时:

cin >> f >> x;

真正发生的是你的函数被调用与之前相同,但它返回cin。由于没有重载&gt;&gt;为istream和int定义,cin将被正常处理。

首先,计算机会计算:

cin >> f;

你的功能超载了。然后计算机计算:

cin >> x;

这是cin和整数的正常操作。

您的行也会发生同样的事情:

os << array[i] << "\n";

在那:

os << array[i];
首先处理

,然后:

os << "\n";

得到处理。

从技术上讲,在这两种情况下,您的流对象都会被返回,但是没有使用返回的值,所以它只是被丢弃了。这就像一条线说的那样:

sqrt(81);

由于没有用于存储返回值的变量,计算机将计算该值,然后将其丢弃(或者如果编译器是智能的,则完全跳过它)。