简单的C++类初始化中的不明确概念,希望朋友帮忙解决!
#include <iostream>
class Date
{
int month,day,year;
public:
Date(int m=0, int d=0, int y=0)
{
month = m;
day = d;
year = y;
}
void display()
{
std::cout<<month<<'/'<<day<<'/'<<year<<std::endl;
}
~Date()
{
std::cout<<"Calling Destructor!"<<std::endl;
}
};
int main()
{
Date date1(2,2,2004);
date1.display();
Date* date2 = new Date(10,21,1981);
date2->display();
delete date2;
return 0 ;
}
这是我写的代码,不明白的地方如下:
1、Date date1(2,2,2004);这个语句是否在堆中分配空间,还是在栈上分配空间,经测试实用这个方式产生的date1在程序结束时自动调用 析构函数,这是为什么,难道因为是在栈上分配的局部变量到了生存期末自动销毁?
2、使用 Date* date2 = new Date(10,21,1981); 在堆上分配空间,那么date2这个指针是否放在栈上,程序必须通过delete date2;方能调用析构函数,如果date2是放在栈上的指针,指向堆空间地址上的类空间,那么在程序结束时为何不自动调用析构函数?
3、这两种使用类的方式用哪种比较合理?
希望各位畅所欲言,各抒己见。/
问题点数:0、回复次数:10Top
1 楼Panic_1(觉觉ing)回复于 2005-02-23 14:07:14 得分 0
1,栈,栈对象在退栈的时候会自动调用析构。
2,date2在栈上,指向堆空间。退栈时,系统会自动“析构”这个指针,而不是指针所指向的对象。考虑下面的情况
Date d;
Date *p = &d;
Date *p1 = &d;
//...
如果退栈时自动调用p,p1所指向对象的析构,会怎样?
3,具体问题具体分析。
Top
2 楼sjssunjs(大海)回复于 2005-02-23 14:45:02 得分 0
date1是在栈上分配,date2在堆上分配空间,在C++中,用的二种方法最好,因为new在C++中含义非常深刻,在new的过程中,已经自动调用了类的构造函数,同事,如果你使用了new,就可以使用delete来释放对象,在delete过程中,自动调用对象的析构函数来把对象释放。所以从代码的健壮性出发,建议你用new来初始化对象!Top
3 楼AOM(spaces.msn.com/aom7610)回复于 2005-02-23 14:59:44 得分 0
Date d;
Date *p = &d;
Date *p1 = &d;
//...
如果退栈时自动调用p,p1所指向对象的析构,会怎样?
那么退栈时,自动调用p所指的析构是正常了,而p1指向的对象不存在了,产生问题了!
Top
4 楼ioriogami(八极推手er——VF铁杆非伪)回复于 2005-02-23 16:14:07 得分 0
我的理解是这样的:d,p,p1都在栈上时,不存在根据指针找对象并释放的问题。
Date d;
Date *p = &d;
Date *p1 = &d;
这三句话在退栈时,只是将p1,p,d三个变量所占的内存回收即可。具体就是将p1
所占内存(4字节)释放,p所占内存(4字节)释放,将d所占内存(sizeof(Date)个字节)释放.
Top
5 楼ioriogami(八极推手er——VF铁杆非伪)回复于 2005-02-23 16:19:04 得分 0
当然释放d之前会自动调用一次d的析构函数,这样,d的析构函数只会被调用一次,而不是根据有几个指向它的指针来决定。Top
6 楼yc0188(守护瓶(萍))回复于 2005-02-23 16:24:08 得分 0
我想d,p,p1都是在系统栈上生成的.
在d的生存周期到了后,d调用析构函数.至于p,p1都没有关系.只是退栈就行了.Top
7 楼ioriogami(八极推手er——VF铁杆非伪)回复于 2005-02-23 16:29:42 得分 0
其实无论在哪里分配,都不会有自动根据指针释放内存的情况。在堆上分配的内存,由于是运行期对象,编译器不会聪明到能认知其生存周期的地步(否则成垃圾收集器了),所以只能自己手工做,用操作符delete来根据某个指针释放它所指向的堆内存。Top
8 楼paddy102(▄︻┻┳═一)回复于 2005-02-23 17:23:55 得分 0
对于Heap和Stack,简单的来讲,Stack上分配的内存系统自动释放,Heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里。Stack一般是静态分配内存,而Heap上一般是动态分配内存。
下面是Stack和Heap的对比说明:
l. Stack:堆栈本身就具有回收特性,每当程序执行到区块的结束点时,该区块的内存就自动被释放,这让我们没必要担心程序里使用了多少变量,因为变量在区块外立即自动被释放,保证了一直有足够内存空间。堆栈虽好,但可惜的是并不是所有信息都可以存储在堆栈中。例如我们经常使用的string类型变量,之所以把string变量存储在Heap中,是因为字符串的长度是可变的,无法直接在堆栈中分配内存空间,因为堆栈是静态分配内存的。
2. Heap:从堆上分配的内存一定要自己释放, 不然就是术语"内存泄露"了. 配对使用malloc和free, new和delete。Top
9 楼paddy102(▄︻┻┳═一)回复于 2005-02-23 17:24:41 得分 0
http://www.pconline.com.cn/pcedu/empolder/life/0405/373716.html
http://www.trainlinux.com/lifefile/past/20030510-4.txt
这两篇文章可以好好参考一下Top
10 楼zhoujiamurong(有分俺就不要,俺要知识)回复于 2005-03-02 09:26:30 得分 0
markTop




