关于visual c ++:重载提取运算符>>

overloading the extraction operator >> in C++

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Operator overloading

我必须编写一个时钟程序,在该程序中,我可以在重载提取运算符时输入小时、分钟和秒。这些是我的代码:

时钟类型

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
using namespace std;

class clockType
{
public:
   clockType();
   void getTime();
   friend istream& operator>>(istream&, const clockType);
private:
   int hr, min, sec;
}

时钟类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include'clockType.h"
using namespace std;

clockType::clockType()
{
    hr = 0;
    min = 0;
    sec = 0;
}

void clockType::getTime()
{
    while(hr>=24)
        hr = hr - 24;
    while(min>=60)
        min = min - 60;
    while(sec>=60)
        sec = sec - 60;
    cout<<setfill('0')
        <<setw(2)<<hr<<":"
        <<setw(2)<<min<<":"
        <<setw(2)<<sec<<endl;
 }

 istream& operator>>(istream& in, clockType cl)
 {
    in>>cl.hr>>cl.min>>cl.sec;
    return in;
 }

入口点

1
2
3
4
5
6
7
8
9
10
11
12
13
 #include<iostream>
 #include'clockType.h'

 using namespace std;

 int main()
 {
   clockType clock;
   cout<<"Enter hr, min, sec";
   cin>>clock;
   clock.getTime();
   return 0;
 }

没有错误。我的问题是,当我输入hr、min和sec时,它为什么输出00:00:00?>>为什么不将其值传递给对象时钟?


operator>>的签名需要

1
istream& operator>>(istream& in, clockType& cl)

也就是说,它应该接受对clockType实例的引用。

您当前的代码接受一个clockType实例,因此当调用该运算符时,会生成一个clock的临时副本,并由该运算符进行处理。然后,该副本将被丢弃,您的原始clock将保持不变。

这里的另一个问题是,您没有检查是否成功地从输入流中读取了任何内容。在in上的任何和所有>>操作都可能失败,这可能使cl处于未知状态。所以首先,你应该用像if(in >> cl.hr)这样的东西来测试成功。

这还不够,因为第一次读取操作(到hr中)可能成功,但下一次读取操作可能失败;这将使cl处于未知状态。如果提取运算符具有事务语义(即它更新所有三个成员,否则它将使对象保持其以前的状态),那就更好了。实现这一点的一种方法是首先读取局部变量,并且只有当所有三个读取都成功时,才将值复制到cl中。


提取运算符可能会更改传递给它的对象,而不仅仅是它的副本。也就是说,要使提取运算符的第二个参数也成为非常量引用:

1
std::istream& operator>> (std::istream& in, clockType& cl) { ... }

顺便说一句,在使用结果之前,务必检查提取是否有效:

1
if (std::cin >> clock) { ... }


1
istream& operator>>(istream& in, clockType cl)

应该是:

1
istream& operator>>(istream& in, clockType &cl)   // (note the &)

您必须引用operator>>中的clocktype对象,否则它将只读取到函数本地对象中。