草庐IT

c++ - 重载 '-' 运算符

coder 2024-02-24 原文

目前我正在编写一个程序,其中有一个部分用于确定两个日期之间的天数差异,但是通过重载减号运算符。

我目前正盯着我的屏幕画一片空白。我脑子里有一些转瞬即逝的想法,但它们就是那样,转瞬即逝。

main.cpp 中将发生的事情是将有两个变量,例如 beethovenDeathDatebeethovenBirthDate 将减去这两个变量以确定他的生命周期为了。如果我没记错的话,大约是 22000 天。

所以事不宜迟,这是我的代码:

日期.cpp

const std::string Date::MONTH_STRINGS[] = 
{
    "", //one based indexing
    "January",
    "February",
    "March",
    "April",
    "May", 
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};

const int Date::DAYS_PER_MONTH[] =
{
    0, //one based indexing
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};      

Date::Date(int day, int month, int year) : _year(year), _month(month), _day(day)
{
    isValid();
}

Date::Date()
{
    time_t t = time(0);   // get time now
    struct tm * now = localtime( & t );
    _year = now -> tm_year + 1900;
    _month = now -> tm_mon + 1;
    _day = now -> tm_mday;
}

int Date::maxDay(int month, int year)
{
    int ret = DAYS_PER_MONTH[month];
    if(isLeapYear(year) == true && month == 2)
    {
        ++ret;
    }
    return ret;
}

void Date::addDay(bool forward)
{
    if(forward)
    {
        if(_day < maxDay(_month, _year))
        {
            ++_day;
        }
        else
        {
            _day = MIN_DAY;
            ++_month;
            if(_month > MAX_MONTH)
            {
                _month = MIN_MONTH;
                ++_year;
            }    
        }
    }
    else
    {
        if(_day <= MIN_DAY)
        {
            --_month;
            if(_month < MIN_MONTH)
            {
                _month = MAX_MONTH;
                --_year;
            } 
            _day = maxDay(_month, _year);
        }
        else
        {
            --_day;
        }
    }    
}


std::string Date::toString() const
{
    if(isValid() == false)
    {
        return std::string();
    }
    std::stringstream ss;
    ss  << MONTH_STRINGS[_month] << " " << _day << ", " <<  _year;
    return ss.str();            
}    


bool Date::isValid() const
{
    if(_month < MIN_MONTH || _month > MAX_MONTH)
    {
        std::cerr << "Invalid date " << std::endl;
        return false;
    }
    int daysThisMonth = maxDay(_month, _year);

    if(_day < MIN_DAY || _day > daysThisMonth)
    {
        std::cerr << "Invalid date " << std::endl;            
        return false;   
    }
    return true;
}

bool Date::isLeapYear(int year)
{
    if(!(year % 4))
    {
        if(!(year % 100))
        {
            if(!(year % 400))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }
    }
    else
    {
        return false;
    }
}

bool Date::isLeapYear() const
{
    return isLeapYear(_year);
}

bool Date::isLeapDay() const
{
    return isLeapDay(_day, _month, _year);
}

bool Date::isLeapDay(int day, int month, int year) 
{
    if(day == 29 &&  month == 2 && isLeapYear(year) == true)
    {
        return true;
    }
    else
    {
        return false;
    }
}


void Date::addYears(int years)
{
    if(years == 0)
    {
        return;
    }
    if(isLeapDay() && !isLeapDay(_day, _month, _year + years))
    {
        _day = Date::DAYS_PER_MONTH[_month];
    }
    _year += years;
}

void Date::addMonths(int months)    
{
    if(months == 0)
    {
        return;
    }
    int deltayears = months / MAX_MONTH;
    int deltamonths = months % MAX_MONTH;
    int newMonth = 0;
    if(months > 0)
    {
        newMonth = (_month + deltamonths) % MAX_MONTH;
        if((_month + deltamonths) > MAX_MONTH)
        {
            ++deltayears;
        }
    }
    else
    {
        if((_month + deltamonths) < MIN_MONTH)
        {
            --deltayears;
            newMonth = _month + deltamonths + MAX_MONTH;
        }
        else
        {
            newMonth = _month + deltamonths;
        }       
    }
    if(_day > maxDay(newMonth, _year + deltayears))
    {
        _day = maxDay(newMonth, _year + deltayears);
    }
    _year += deltayears;
    _month = newMonth;

}

void Date::addDays(int days)
{
    if(days == 0)
    {
        return;
    }

    if(days < 0)
    {
        for(int i = 0; i > days; --i)
        {
            addDay(false);
        }
        return;
    }

    for(int i = 0; i < days; ++i)
    {
        addDay(true);
    }
}

std::ostream& operator<<(std::ostream& os, const Date& date)
{
    os << date.toString();
    return os;
}

Date Date::operator+(int days) const
{
    Date ret = *this;
    ret.addDays(days);
    return ret;
}

Date& Date::operator+=(int days)
{
    addDays(days);
    return *this;
}
//This is where I get stumped (the parameters was just one of my failed experiments
Date& Date::operator-(int day, int month, int year)
{
}

最佳答案

函数可以写成成员函数,也可以写成自由函数。成员函数签名如下所示:

TimeDuration Date::operator-(Date const & rhs) const

免费功能看起来像这样:

TimeDuration operator-(Date const & lhs, Date const & rhs)

TimeDuration 这里是一个完全独立的类型,表示时间长度。如果需要,您可以将其设为表示天数的 int,但在我看来,为此目的使用更具表现力的类型会更好。无论您对返回类型做出何种决定,类型为 Date(当然也不是 Date&)都没有任何意义。

假设您已经编写了一个向日期添加一天的函数,一个可能的(尽管不是非常有效)实现是这样的:

if lhs_date comes before rhs_date
    add days to (a copy of) lhs_date until lhs_date == rhs_date
    return the negative of number of days added
if rhs_date comes before lhs_date
    add days to (a copy of) rhs_date until rhs_date == lhs_date
    return the number of days added
else
    return 0

您可能需要的另一个函数(或者这可能是您最初真正想要的,但您的措辞并未表明)是一个可以从 Date 中减去时间长度的函数。在这种情况下,返回值将是另一个 Date 对象(但不是 Date&),并且可能的签名看起来像这样:

Date Date::operator-(TimeDuration rhs) const // member version
Date operator-(Date const & lhs, TimeDuration const & rhs) // non-member version

关于c++ - 重载 '-' 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18709604/

有关c++ - 重载 '-' 运算符的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  9. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  10. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

随机推荐