这里有坑,这里有坑,这里有坑
首选我们直接上代码,因为代码是很简单的,但是有一些语法结构是有坑的
//日期之间相差多少天 int Date::operator-(const Date& d)const { //这里采取假设法,假设this是大的,如果不是,则进行转换 Date max = *this; Date min = d; int flag = 1; if (*this < d) { max = d; min = *this; flag = -1; } int cout = 0; while (max != min) { ++min; ++cout; } return cout* flag; } //测试 int main() { Date ret6 = d6 + 10000; ret6.print(); //首先,编译器尝试寻找一个可以处理d6 + 10000的操作符重载函数,比如operator + (int), //如果没有找到这样的函数。 //然后,编译器可能会尝试将d6 + 10000解释为d6.operator+(Date(10000)), //也就是先通过单参数构造函数将整数10000转换为一个临时的Date对象, //然后再尝试调用可能存在的operator + (const Date&)成员函数来执行加法操作。 // // 两个解决办法 // 1, explicit Date(int value); //使用explicit关键字后,编译器将不会自动使用这个单参数构造函数进行隐式类型转换,从而避免了意 外的行为。 // 2,加上const修饰 //测试日期类的减等和减 Date d7; d7 -= 10000; d7.print(); Date d8(2000,1,1); Date ret8 = d8 - 1000; //原因是:1000但参构造成为了Date对象,导致调用不明确 禁止掉可以解决折扣的问题 ret8.print(); //如果你给那个函数加上了const就只有const对象可以调用 不会出现调用不明确了 RETURN 0; }
逻辑注意:
- 首先我们实现逻辑的时候,不能真的这个用日期和日期直接相互减减,因为那样会很麻烦
- 所以我们可以直接利用追击问题,当数值一样的时候,我们就可以跳出循环
实现逻辑
- 首先进行大小判断和初始化:
Date max = *this;
和Date min = d;
以及int flag = 1;
这几行代码假设当前对象(*this
)是较大的日期,将其赋值给max
,传入的参数对象d
赋值给min
,并设置标志变量flag
为 1。- 如果当前对象实际上小于传入的对象,即
*this < d
,则进行交换:max = d;
和min = *this;
,同时将标志变量flag
设为 -1。这样确保max
始终是较大的日期,min
始终是较小的日期。- 然后计算日期差:
- 使用一个循环
while (max!= min)
,只要两个日期不相等就继续循环。- 在循环中,每次将较小的日期
min
递增一天(这里假设Date
类实现了自增运算符++
,使其能够正确地增加一天,同时处理月份和年份的变化),并将天数计数器cout
加一。- 当两个日期相等时,循环结束。
- 最后返回结果:
- 将天数计数器
cout
乘以标志变量flag
,得到最终的日期差。如果一开始假设正确,即当前对象较大,那么返回正数的日期差;如果当前对象较小,返回负数的日期差。这里有坑的点:
所以还是回到那一句话,const应加尽加
解决办法一:使用 explicit 关键字
在单参数构造函数上面加上
explicit
关键字,例如explicit Date(int value)
。使用explicit
关键字后,编译器将不会自动使用这个单参数构造函数进行隐式类型转换,从而避免可能出现的调用歧义。解决办法二:对成员函数进行 const 修饰
对于
int operator-(const Date& d) const;
这个成员函数加上const
修饰。这里加上const
修饰可以解决调用歧义的原因是:这个函数的返回值是int
类型,也就是常量。常量具有不可修改的特性,所以就不会导致调用歧义。
日期类的实现- 计算日期之间相差多少天-解决单参数构造
于 2024-09-27 12:51:40 首次发布