2013-05-05 125 views
0

出于某种原因,当我使用的析构函数我更新类,调试断言失败消息显示...调试断言失败的消息

这里是我的更新类略去了一些代码。放置在头文件中:

using namespace std; 

class Update 
{ 
private: 
    int day, month, year; 
static const int FIELD_SIZE = 3, DEFAULT_DAY = 12, DEFAULT_MONTH = 12, 
    DEFAULT_YEAR = 1999, DAYS_IN_MONTH = 30, MONTHS_IN_YEAR = 12, DAYS_IN_YEAR = 365; 

int * date; 

public: 
static int dateUpdate; 

Update(int D, int M, int Y) 
{ 
    day = D; 
    if (day < 1 || day > DAYS_IN_MONTH) 
     day = DEFAULT_DAY; 
    month = M; 
    if (month < 1 || month > MONTHS_IN_YEAR) 
     month = DEFAULT_MONTH; 
    year = Y; 
    if (year < 1) 
     year = DEFAULT_YEAR; 

    date = new int [FIELD_SIZE]; 
    date[0] = day, date[1] = month, date[2] = year; 

    dateUpdate++; 
} 

~Update() 
{ 
    delete [] date; 

    dateUpdate--; 
} 

};

,这里是一个CPP文件我的测试类:

#include <iostream> 
#include "Update.h" 

int Update::dateUpdate = 0; 

int main() 
{ 
Update u1(29, 12, 2000); 
u1.Update::~Update(); 

return 0; 
} 

我已经通过涉及调试断言失败等问题,读,但东西告诉我一个调试断言失败以不同的方式,可能会发生。结果,我很少知道为什么错误信息显示在我的代码中......现在我怀疑我的析构函数有什么问题吗?非常感谢你的帮助!

+3

为什么你明确地调用析构函数? – olevegard 2013-05-05 19:24:40

+0

为什么你使用'new []'和'delete []'而不是一个容器为你做了繁重的工作(你已经做了错误的例子)? – chris 2013-05-05 19:25:44

+0

难道不是这样做的吗?我当时正在看msdn.microsoft.com/en-us/library/35xa3368%28v=vs.80%29.aspx ... – user1800967 2013-05-05 19:25:59

回答

1

您应该更改此行:
date [0] = day,date [1] = month,date [2] = year;

要:

date[0] = day; 
date[1] = month; 
date[2] = year; 

您正在使用逗号操作,它返回最后一个表达式的结果。这与逗号在初始化中的操作方式不同。

此外,在您的main函数中,您不需要显式调用析构函数。

你的约会方法不能处理的1月31日,也没有12月31日

您可以访问函数的参数,而不是直接在功能上进行复印。例如:day = D;是不需要的;直接访问参数:if ((D < 1) ...

如果使用无符号整数,则不需要检查负数。我从未经历过我的生活中的一天,一年或一年。

由于这是C++而不是Java或C#,因此不需要动态分配变量。因此,您可以使用int date[3]而不是使用int * date

+0

使用逗号仍然有效(它会将每个值赋给每个变量),但绝对不是好习惯。 – chris 2013-05-05 19:30:28

+0

对于我正在进行的具体任务,负数很好。所以很酷。谢谢。 – user1800967 2013-05-05 19:47:23

2

的问题是,因为你是显式调用析构函数:

u1.Update::~Update(); 

这种方式被称为两次导致未定义的行为,我想删除[]日期;被称为两次,第二次在alreade释放记忆。

在你的代码的另一个问题是,你正在使用裸指针数组你:

int * date; 

这其实是在C语言相当低级别的编程风格++,并可能导致很多问题。您应该实现类复制构造函数和赋值运算符(*),它将在您的Update类将被复制时分配新的日期数组,否则您将再次遇到多个日期指针删除的问题。

的最好方法是使用像

std::vector<int> date; 

(*)载体,我认为很好的链接,其中的规则,三个(或因为C++ 11的5种规则)此处适用解释:Rule-of-Three becomes Rule-of-Five with C++11?

+0

这就是手动内存管理如此糟糕的原因。你忽略提到需要一个赋值运算符,并且在C++ 11中需要移动这些运算符的版本。此外,对对象调用析构函数两次本身也是未定义行为,即使它是空的。 – chris 2013-05-05 19:42:07