注册 登录
编程论坛 C++教室

[讨论]看下这段程序中类里的红色代码的意义是什么?

ioriliao 发布于 2007-06-20 09:36, 778 次点击


#include <iostream>
#include <cstdlib>
#include "File1.h"
using namespace std;

class CDateinfo
{
public:
CDateinfo();
CDateinfo(int year, int month, int day);
~CDateinfo();
void SetDate(int year, int month, int day);
void GetDate();
private:
int year;
int month;
int day;
};

CDateinfo::CDateinfo()
{
this->year = 2007;
this->month = 5;
this->day = 23;
}

CDateinfo::CDateinfo(int year, int month, int day)
{
this->year = year;
this->month = month;
this->day = day;
}

CDateinfo::~CDateinfo()
{
cout << "Unload me" << endl;
this->year = 0;
this->month = 0;
this->day = 0;
}

void CDateinfo::SetDate(int year, int month, int day)
{
this->year = year;
this->month = month;
this->day = day;
}

void CDateinfo::GetDate()
{
cout << "当前日期为: " << this->year << "年"
<< this->month << "月"
<< this->day << "日"
<<endl;
}

int main()
{
CDateinfo* MyDate = new CDateinfo;
MyDate->GetDate();
cout << "执行delete后自动调用析构函数" << endl;
delete MyDate;


cout << endl << endl;

CDateinfo* ThisDate = new CDateinfo(2007, 5, 23);
ThisDate->GetDate();
delete ThisDate;

cout << endl <<endl;

CDateinfo* OtherDate = new CDateinfo;
OtherDate->SetDate(2008,8,8);
OtherDate->GetDate();
delete OtherDate;

cout << endl << endl;

cout << "注意delete OtherDate 后再次调用 OtherDate 的GetDate方法" << endl;
OtherDate->GetDate();

system("pause");
return 0;
}
//---------------------------------------------------------------------------


在类中的析构函数中我加入了
this->year = 0;
this->month = 0;
this->day = 0;
然后delete了OtherDate后再调用GetDate方法,我在dev-c中运行的结果是 0年0月0日的,其它的编译器就是乱来的.
然后我在dev-c中调试,单步进入,到了this->year = 0;这句之后就不能再运行到下一步了.

9 回复
#2
HJin2007-06-20 09:47
you are seeking some undefined behavior of deleted objects. The rule is:

Once an obj goes out of scope or gets destroyed, any later reference to the obj is undefined behavior. Period.

Although a particular complier may still let you access the obj, you should not rely on the complier.


[QUOTE] this->year = 0;
this->month = 0;
this->day = 0;[/QUOTE]
This code snippet in the dtor is okay --- the body of the dtor is executed first, then the memory for year, month, day, is freed.

delete OtherDate;
......

[CODE] OtherDate->GetDate();[/CODE]
This code snippet should not be there by all means; otherwise, you are risking getting fired by your boss.

#3
ioriliao2007-06-20 10:56
E文的原因,看得不是很明白....
#4
aipb20072007-06-20 11:25
to ioriliao:

不是其他编译器乱来,只是编译器对之中为定义行为处理不同吧!
你把对象都销毁了,怎么还能调用它的方法呢?

还有,我觉得你析够里的代码纯粹多余,因为即使你定义了自己的析够,编译器仍然会合成一个析够,在你调用你自己的析够之后调用。所以这个合成的析够会释放掉当前对象的数据信息。
#5
aipb20072007-06-20 11:39
补充一点,合成析够只会销毁当前数据成员。
比如 int *p = new ...

只会销毁p,但是p指向的动态内存会遗留下来,这就是内存泄露。
所以这又牵扯到析够函数的必要性,就离远了哈!
hoho ~
#6
ioriliao2007-06-20 11:57
我说的那个乱来非彼乱来,意思是不确定性....
呵呵...加那代码我就是想看看会发生什么事情...

#7
aipb20072007-06-20 12:38
你真有探索精神!
呵呵~
#8
wfpb2007-06-20 13:50

在析构函数中置0,析构函数结束后,存储数据的地址根据编译器的操作不同有可能不改变那些地址存放的数据,但有些编译器也会至为未知数。。。
所以在析构函数之后可以使那些值修改然后GetData();


delete OtherDate;
cout << endl << endl;
cout << \"注意delete OtherDate 后再次调用 OtherDate 的GetDate方法\" << endl;
OtherData.SetData(0,0,0);//要在析构之后设置该内存地址中的数据。
OtherDate->GetDate();

#9
ioriliao2007-06-20 14:15

为什么delete了一个对象,还可以使用这个对象,
就是说进行这个对象的方法调用不会出错.

#10
wfpb2007-06-20 20:00
因为一个类的所有对象都是公用成员函数,所以即便某个对象delete了,他的成员函数所在的地址仍然有效。
class A
{
    int a;
public:
    A(){a=0;}
    void show()
    {
        cout<<a<<endl;
    }
};

想必你也知道,a.show()相当于show(&a);
而void A::show(){cout<<a<<endl;}
相当于void show(A* this){cout<<this->a<<endl;}
所以成员函数实际上会根据this指针来对此对象(以this指针指向的sizeof(A)这块内存区域构成的对象)的数据做操作.

可以拿下面的测试程序做参考:

void main()
{
    A *pa=new A;
    int a=10;
    delete pa;
    pa=(A*)&a;
    pa->show();    //输出10
}

1