第九周项目二 Time类中的运算符重载(续)

本文介绍了一个C++程序实例,展示了如何通过运算符重载实现Time类的多种操作,包括比较、加减及自增自减等,并实现了时间的输入输出功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
*Copyright (c)2014,烟台大学计算机与控制工程学院
*All rights reserved.
*文件名称:test.cpp
*作    者:徐洪祥
*完成日期:2015年5月16日
*版 本 号:v1.0
*
* 问题描述:实现Time类中的运算符重载(续),定义对时间对象的自增和自减一目运算符,定义Time类中的<<和>>运算符重载,
            实现时间的输入输出,改造原程序中对运算结果显示方式,使程序读起来更自然。
* 输入描述:
* 程序输出:
*/
#include <iostream>
using namespace std;
class CTime
{
private:
    unsigned short int hour;    // 时
    unsigned short int minute;  // 分
    unsigned short int second;  // 秒
public:
    CTime(int h=0,int m=0,int s=0);
    void setTime(int h,int m,int s);
    friend istream &operator>>(istream &input,CTime &c);
    friend ostream &operator<<(ostream &output,CTime c);
    //二目的比较运算符重载
    bool operator > (CTime &t);
    bool operator < (CTime &t);
    bool operator >= (CTime &t);
    bool operator <= (CTime &t);
    bool operator == (CTime &t);
    bool operator != (CTime &t);
    //二目的加减运算符的重载
    //返回t规定的时、分、秒后的时间
    //例t1(8,20,25),t2(11,20,50),t1+t2为19:41:15
    CTime operator+(CTime &t);
    CTime operator-(CTime &t);//对照+理解
    CTime operator+(int s);//返回s秒后的时间
    CTime operator-(int s);//返回s秒前的时间
    //二目赋值运算符的重载
    CTime operator+=(CTime &c);
    CTime operator-=(CTime &c);
    CTime operator+=(int s);//返回s秒后的时间
    CTime operator-=(int s);//返回s秒前的时间
    CTime operator++(int);//后置++,下一秒
    CTime operator++();//前置++,下一秒
    CTime operator--(int);//后置--,前一秒
    CTime operator--();//前置--,前一秒
};
ostream& operator<<(ostream& output,CTime c)
{
    output<<c.hour<<":"<<c.minute<<":"<<c.second;
    return output;
}
istream &operator>>(istream &input,CTime &c)
{
    char a;
    while(1)
    {
        cout<<"请输入时间(hh:mm:ss):"<<endl;
        input>>c.hour>>a>>c.minute>>a>>c.second;
        if(c.hour<24&&c.hour>-1&&c.minute<60&&c.minute>-1&&c.second<60&&c.second>-1&&a==':')
            break;
        else
            cout<<"格式错误,请重新输入\n"<<endl;
    }
    return input;
}
CTime::CTime(int h,int m,int s)
{
    hour=h;
    minute=m;
    second=s;
}
void CTime::setTime(int h,int m,int s)
{
    hour=h;
    minute=m;
    second=s;
}
bool CTime::operator > (CTime &t)
{
    if(hour>t.hour)
        return true;
    if(hour<t.hour)
        return false;
    if(minute>t.minute)
        return true;
    if(minute<t.minute)
        return false;
    if(second>t.second)
        return true;
    return false;
}
bool CTime::operator < (CTime &t)
{
    if(hour<t.hour)
        return true;
    if(hour>t.hour)
        return false;
    if(minute<t.minute)
        return true;
    if(minute>t.minute)
        return false;
    if(second<t.second)
        return true;
    return false;
}
bool CTime::operator >= (CTime &t)
{
    if(*this<t)
        return false;
    else
        return true;
}
bool CTime::operator <= (CTime &t)
{
    if(*this>t)
        return false;
    else
        return true;
}
bool CTime::operator == (CTime &t)
{
    if (*this < t || *this > t)
        return false;
    else
        return true;
}
bool CTime::operator != (CTime &t)
{
    if(*this==t)
        return false;
    else
        return true;
}
CTime CTime::operator+(CTime &t)
{
    int h,m,s;
    h=hour+t.hour;
    m=minute+t.minute;
    s=second+t.second;
    if(s>59)
    {
        s-=60;
        m++;
    }
    if(m>59)
    {
        m-=60;
        h++;
    }
    if(h>23)
    {
        h-=24;
    }
    CTime t0(h,m,s);
    return t0;
}
CTime CTime::operator-(CTime &t)
{
    int h,m,s;
    h=hour-t.hour;
    m=minute-t.minute;
    s=second-t.second;
    if(s<0)
    {
        s+=60;
        m--;
    }
    if(m<0)
    {
        m+=60;
        h--;
    }
    if(h<0)
    {
        h+=24;
    }
    CTime t0(h,m,s);
    return t0;
}
CTime CTime::operator+(int s)
{
    int ss=s%60;
    int mm=(s/60)%60;
    int hh=s/3600;
    CTime t0(hh,mm,ss);
    return *this+t0;
}
CTime CTime::operator-(int s)
{
    int ss=s%60;
    int mm=(s/60)%60;
    int hh=s/3600;
    CTime t0(hh,mm,ss);
    return *this-t0;
}
CTime CTime::operator+=(CTime &C)
{
    *this=*this+C;
    return *this;
}
CTime CTime::operator-=(CTime &C)
{
    *this=*this-C;
    return *this;
}
CTime CTime::operator+=(int s)
{
    *this=*this+s;
    return *this;
}
CTime CTime::operator-=(int s)
{
    *this=*this-s;
    return *this;
}
//一目运算符的重载
CTime CTime::operator++(int)//后置++,下一秒
{
    CTime t=*this;
    *this=*this+1;
    return t;
}
CTime CTime::operator++()//前置++,下一秒
{
    *this=*this+1;
    return *this;
}
CTime CTime::operator--(int)//后置--,前一秒
{
    CTime t=*this;
    *this=*this-1;
    return t;
}
CTime CTime::operator--()//前置--,前一秒
{
    *this=*this-1;
    return *this;
}
int main()
{
    CTime t1,t2,t;
    cout<<"t1为:";
    cin>>t1;
    cout<<"t2为:";
    cin>>t2;
    if (t1>t2)
        cout<<"t1>t2"<<endl;
    if (t1<t2)
        cout<<"t1<t2"<<endl;
    if (t1==t2)
        cout<<"t1=t2"<<endl;
    if (t1!=t2)
        cout<<"t1!=t2"<<endl;
    if (t1>=t2)
        cout<<"t1>=t2"<<endl;
    if (t1<=t2)
        cout<<"t1<=t2"<<endl;
    cout<<endl;
    cout<<"t1+t2="<<t1+t2<<endl;
    cout<<"t1-t2="<<t1-t2<<endl;
    cout<<"t1返回2000s后的时间:"<<t1+2000<<endl;
    cout<<"t1返回2000s前的时间:"<<t1-2000<<endl;
    cout<<"t=t1++"<<endl;
    t=t1++;
    cout<<"t= "<<t<<"    t1= "<<t1<<endl;
    cout<<"t=++t1"<<endl;
    t=++t1;
    cout<<"t= "<<t<<"    t1= "<<t1<<endl;
    cout<<"t=t1--"<<endl;
    t=t1--;
    cout<<"t="<<t<<"     t1= "<<t1<<endl;
    cout<<"t=--t1"<<endl;
    t=--t1;
    cout<<"t="<<t<<"     t1= "<<t1<<endl;
    return 0;
}




总结:注意时分秒是私有的,写形参时注意"&" 的运用


<think>好的,我现在需要帮助用户解决如何在C++重载<<和>>运算符,以处理自定义Time的输入输出,并且要求格式化两位数字。首先,我要回顾一下用户提供的引用资料,确保正确应用这些知识点。 根据引用[2]和引用[5],输出运算符<<的重载函数第一个参数是ostream的引用,不能是const,第个参数是的const引用。输入运算符>>的重载第一个参数是istream引用,第个参数是的非const引用。同时,这些重载通常作为友元函数,因为需要访问的私有成员。 用户的需求是处理Time,比如输出格式为HH:MM:SS,并且各部分保持两位数字,不足补零。例如,如果小时是9,应该显示为09。这里需要用到流操作符,比如setw(2)和setfill('0'),但要注意这些操作符的使用方法,可能需要包含<iomanip>头文件。 接下来,我需要考虑如何编写Time的结构。假设Time有三个私有成员:hour、minute、second。构造函数或其他方法可能需要验证输入的有效性,比如小时不超过23,分钟和秒不超过59。 对于输出运算符<<的重载,函数应该接收ostream&和一个const Time&,然后按照格式输出。注意设置宽度和填充字符,并且在输出后恢复流的原有状态,避免影响后输出。例如,使用setw(2)设置两位,当数值不足两位时,左侧补零。但需要注意,setw(2)只对下一个输出有效,所以每个部分都需要单独设置。 输入运算符>>的重载则需要处理用户输入,可能遇到格式问题,比如用户输入的分隔符是否正确。比如,用户可能输入HH:MM:SS,函数需要读取每个部分,并跳过中间的冒号。此时,可以使用get()方法读取冒号,或者使用ignore()函数。同时,要检查输入是否有效,如果输入失败,需要设置流的失败状态。 此外,输入时可能需要处理错误情况,比如用户输入了非数字字符或格式不符,这时应该将流的状态设为failbit,以便调用者能检测到错误。 现在,我需要将这些思路转化为代码。首先定义Time,包含私有成员和友元函数声明。然后实现运算符重载函数,注意格式控制和错误处理。同时,测试代码示例也很重要,让用户看到如何实际使用这些重载运算符。 可能需要注意的细节包括:setw(2)和setfill('0')的使用是否正确,是否需要临时保存和恢复流的状态;输入时如何处理分隔符,以及如何确保输入的数字在合理范围内。例如,小时不能超过23,分钟和秒不超过59。这部分验证应该在输入运算符中进行,如果超出范围,设置流的失败状态。 总结步骤:定义Time,声明友元运算符重载,实现输出运算符,格式化每个部分为两位,使用setw和setfill;实现输入运算符,读取各部分并检查格式和有效性。最后,编写测试代码,演示输入输出过程。</think>要在C++中为自定义`Time`实现输入输出运算符`<<`和`>>`的重载,并保证时间格式化为两位数字,可按照以下步骤操作: --- ### 1. 定义Time 首先定义包含时、分、秒成员变量的,并声明运算符重载为友元函数: ```cpp #include <iostream> #include <iomanip> class Time { private: int hour; // 0-23 int minute; // 0-59 int second; // 0-59 public: Time(int h = 0, int m = 0, int s = 0) : hour(h), minute(m), second(s) {} // 声明友元运算符重载(输入输出需要访问私有成员) friend std::ostream& operator<<(std::ostream& os, const Time& t); friend std::istream& operator>>(std::istream& is, Time& t); }; ``` --- ### 2. 实现输出运算符`<<` ```cpp std::ostream& operator<<(std::ostream& os, const Time& t) { // 保存原始流状态 char fill = os.fill('0'); std::ios_base::fmtflags flags = os.flags(); // 输出两位数格式(自动补零) os << std::setw(2) << t.hour << ":" << std::setw(2) << t.minute << ":" << std::setw(2) << t.second; // 恢复流状态 os.fill(fill); os.flags(flags); return os; } ``` - `std::setw(2)`设置输出宽度为2位,不足时左侧补零[^5] - 通过`os.fill('0')`设置填充字符为零 - 保存并恢复流状态避免影响其他输出操作[^1] --- ### 3. 实现输入运算符`>>` ```cpp std::istream& operator>>(std::istream& is, Time& t) { char delimiter1, delimiter2; is >> t.hour >> delimiter1 >> t.minute >> delimiter2 >> t.second; // 验证分隔符和数值范围 if (delimiter1 != ':' || delimiter2 != ':' || t.hour < 0 || t.hour > 23 || t.minute < 0 || t.minute > 59 || t.second < 0 || t.second > 59) { is.setstate(std::ios::failbit); // 设置错误状态 } return is; } ``` - 通过`:`作为分隔符读取时间分量 - 检查数值有效性,若非法则设置流错误状态[^4] - 错误处理示例:输入`25:70:99`会触发错误 --- ### 4. 使用示例 ```cpp int main() { Time t1; std::cout << "输入时间(HH:MM:SS):"; std::cin >> t1; // 例如输入"9:5:3" std::cout << "格式化输出:" << t1 << "\n"; // 输出"09:05:03" return 0; } ``` --- ### 关键特性说明 | 功能 | 实现方法 | |----------------|--------------------------------------------------------------------------| | 输出补零 | 组合使用`std::setw(2)`和`os.fill('0')` | | 流状态保护 | 保存/恢复`fill`字符和格式标志 | | 输入验证 | 检查分隔符和数值范围,设置`failbit` | | 运算符重载型 | 必须使用友元函数(因左侧操作数为流对象,无法通过成员函数实现)[^2][^3] | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值