我正在尝试做 Bjarne Stroustrup 的书“ Programming: Principles and Practice using C++ ”第 9 章末尾的练习。我从书中复制了大部分代码,只需要定义Date
类的成员函数add_day()
, add_month()
,add_year()
和重载+
运算符即可使用Chrono::Date::Month
枚举。
我的问题是程序可以编译,但是当我Chrono::Date::add_month()
在main()
. add_month()
是唯一在枚举上使用重载+
运算符的函数。Month
其他两个成员函数 (add_day()
和add_year()
) 在main()
. 当我正在做add_month()
直接做的事情时main()
(不使用该功能),它工作正常。
崩溃发生在 Chrono.cpp 的第 100 行,错误为“堆栈溢出”:
Date::Month& operator + (Date::Month& m, int n) {
这是我的代码:
计时.h:
#include "../../std_lib_facilities.h"
namespace Chrono {
class Date {
public:
enum Month {
jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
};
class Invalid {}; // à utiliser comme exception
Date(int yy, Month mm, int dd); // vérifie la validité et initialise
Date(); // constructeur par défaut
//opérations non modificatrices:
int day() const {return d;}
Month month() const {return m;}
int year() const {return y;}
//opérations modificatrices:
void add_day(int n);
void add_month(int n);
void add_year(int n);
private:
int y;
Month m;
int d;
};
bool is_date(int y, Date::Month m, int d); // vrai pour une date valide
bool leapyear(int y); // vrai si l'année est bissextile
int days_in_month(Date::Month m, int y);
bool operator == (const Date& a, const Date& b);
bool operator != (const Date& a, const Date& b);
ostream& operator << (ostream& os, const Date& d);
istream& operator >> (istream& is, Date& dd);
Date::Month& operator + (Date::Month& m, int n);
}
计时.cpp:
#include "Chrono.h"
namespace Chrono {
// définitions des fonctions membres:
Date::Date(int yy, Month mm, int dd)
:y(yy), m(mm), d(dd) {
if (!is_date(yy,mm,dd)) throw Invalid();
}
Date& default_date() {
static Date dd(2001, Date::jan, 1);
return dd;
}
Date::Date()
:y(default_date().year()), m(default_date().month()), d(default_date().day()) {}
void Date::add_day(int n) {
if((d + n) > days_in_month(m,y)) {
add_month(1);
d = d + n - days_in_month(m,y);
}
else
d += n;
}
void Date::add_month(int n) {
//if ((m + n) > 12) {
// m = m + (n - 12);
// y += 1;
//}
//else
m = m + n;
}
void Date::add_year(int n) {
if (m==feb && d==29 && !leapyear(y+n)) {
m = mar;
d = 1;
}
y += n;
}
bool is_date(int y, Date::Month m, int d) {
// on suppose y valide
if (d<0) return false;
if(days_in_month(m,y) < d) return false;
if(m < Date::jan || m > Date::dec) return false;
return true;
}
bool leapyear(int y) {
if (y % 4 == 0 && y % 100 > 0 || y % 400 == 0)
return true;
else
return false;
}
int days_in_month(Date::Month m, int y) {
int d_i_m = 31;
switch(m) {
case Date::feb:
d_i_m = (leapyear(y))?29:28;
break;
case Date::apr: case Date::jun: case Date::sep: case Date::nov:
d_i_m = 30;
break;
}
return d_i_m;
}
bool operator == (const Date& a, const Date& b) {
return a.year() == b.year() && a.month() == b.month() && a.day() == b.day();
}
bool operator != (const Date& a, const Date& b) {
return !(a==b);
}
ostream& operator << (ostream& os, const Date& d) {
return os << '(' << d.year() << ',' << d.month() << ',' << d.day() << ')';
}
istream& operator >> (istream& is, Date& dd) {
int y, m, d;
char ch1, ch2, ch3, ch4;
is >> ch1 >> y >> ch2 >> m >> ch3 >> d >> ch4;
if (!is) return is;
if (ch1!='(' || ch2!=',' || ch3!=',' || ch4!=')') {
is.clear(ios_base::failbit);
return is;
}
dd = Date(y,Date::Month(m),d);
return is;
}
Date::Month& operator + (Date::Month& m, int n) {
return m + n;
}
enum Day {
sunday, monday, tuesday, wednesay, thursday, friday, saturday
};
//Day day_of_week(const Date& d) {
// // ...
//}
//Day next_Sunday(const Date& d) {
// // ...
//}
//Day next_weekday(const Date& d) {
// // ...
//}
}
main.cpp(工作):
#include "Chrono.h"
int main() {
cout << Chrono::Date::jan + 1;
}
备用 main.cpp (编译但崩溃):
#include "Chrono.h"
int main() {
Chrono::Date date;
date.add_month(1);
}
PS:std_lib_facilities.h 定义了向量、字符串和 IO。它在这里可用。