在C++中重载提取运算符>>

Jul*_*enn 3 c++ visual-c++

可能重复:
运算符重载

我必须编写一个时钟程序,在这个程序中我可以输入小时,分钟和秒,同时重载提取操作符.这些是我的代码:

clockType.h

#include<iostream>
using namespace std;

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

clockType.cpp

#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;
 }
Run Code Online (Sandbox Code Playgroud)

entryPoint.cpp

 #include<iostream>
 #include'clockType.h'

 using namespace std;

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

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

Jon*_*Jon 5

operator>>需要的签名

istream& operator>>(istream& in, clockType& cl) 
Run Code Online (Sandbox Code Playgroud)

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

您当前的代码接受一个clockType实例,因此在调用操作符时,会生成一个临时副本,clock并且操作员可以对其进行操作.然后丢弃该副本,原始文件clock保持不变.

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

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

  • @JulienNicolas:您还需要更新`class clockType`中的`friend`声明以匹配运算符的签名 - 这一点不言而喻. (3认同)