gpt4 book ai didi

c++ - 使用类的成员函数时程序崩溃,但在 main() 中直接实现该函数时不会崩溃

转载 作者:太空狗 更新时间:2023-10-29 20:28:49 25 4
gpt4 key购买 nike

我正在尝试做 Bjarne Stroustrup 的书“Programming: Principles and Practice using C++”第 9 章末尾的练习。我从书中复制了大部分代码,只需要定义 Date 类的成员函数 add_day(), add_month(), add_year(),并重载 + 运算符,使其与 Chrono::Date::Month 枚举一起工作。

我的问题是程序可以编译,但是当我在 main() 中使用 Chrono::Date::add_month() 函数时程序崩溃了。 add_month() 是唯一在 Month 枚举上使用重载的 + 运算符的函数。其他两个成员函数(add_day()add_year())在 main() 中使用时工作正常。当我在 main() 中直接执行 add_month() 的操作时(不使用该函数),它工作正常。

崩溃发生在 Chrono.cpp 的第 100 行,错误为“Stack Overflow”:

    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);
}

P.S: std_lib_facilities.h 定义了 vector 、字符串和 IO。可用here .

最佳答案

Date::Month& operator + (Date::Month& m, int n) {
return m + n;
}

这对您来说可能并不明显,但这是一个递归调用。它不断调用自己,没有终止条件。最终,您通过无限调用此函数来填满堆栈。

关于c++ - 使用类的成员函数时程序崩溃,但在 main() 中直接实现该函数时不会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12134255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com