关于析构函数的问题,大虾们进来讲讲……
本帖最后由 zheguzai 于 2011-04-23 15:31 编辑
- #include <iostream>
- using namespace std;
- class A
- {
- public:
- A();
- ~A();
- void set(int x)
- {
- *i = x;
- }
- int get()
- {
- return *i;
- }
- private:
- int *i;
- };
- A::A()
- {
- cout<<"构造函数运行中……"<<endl;
- i = new int (100);
- cout<<*i<<endl;
- cout<<i<<endl;
- }
- A::~A()
- {
- cout<<"析构函数运行中……"<<endl;
- delete i;
- }
- int main(void)
- {
- A *b;
- b = new A;
- cout<<b<<endl;
- b->set(2);
- cout<<b->get()<<endl;
- delete b;
- return 0;
- }
复制代码上面的代码是我在做实验的时候遇到的,我在堆上为对象开辟了一个空间,但是当我在函数结束时,使用delete来释放new所开辟的空间时,却调用了析构函数,delete不是已经将内存释放掉了么,为什么还会调用析构函数,析构函数的作用不也是释放对象的内存么。但是我要时不用deletel来释放,析构函数就不会执行,这一点我明白,因为在堆上分配的内存,系统是不会自己释放的,由程序员释放的。
我现在的问题是:我已经用delete来释放了在堆上开辟的空间,为什么还会调用析构函数。
请大虾讲讲,小弟不甚感激……
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
构造不是和析构成对出现吗?就跟new了后,就要delete一下,这根编译器有关系吧,我也有点含糊
却调用了析构函数
让我感觉到蛋疼...
delete本来就是执行析构函数,回收内存.
这两个是两码事.
如果是一般的变量,比如,int *i= new int ;
这与的变量的在执行delete时是怎么释放内存的,这个又没析构函数,为什么在释放类的对象是就要调用析构函数
回复 4# zheguzai
内置类型的析构貌似什么事情也没做.
本帖最后由 captivated 于 2011-04-24 16:31 编辑
回复 1# zheguzai
LZ,你是在说:
delete b; // 为什么会调用对象的析构函数?LZ你是说这个是不。
请参考《C++ Primer. Fouth Edition》第13章第3节关于析构函数的内容:何时调用析构函数。
先不涉及new/delete的实现问题,一句话简单地说,当你new一个对象,就会为对象分配内存,并运行构造函数;
当你删除指针,就会调用该指针所指向对象的析构函数。这就是成对的嘛。
而事实上new/delete的实现并不为你调用构造函数/析构函数的。构造函数/析构函数的调用是由编译负责的(你可以
简单地认为编译器为你加上了调用构造函数和析构函数的代码。早期的一些C++编译器事实上是先将C++代码转换
为C代码的,那时事实上就是C++编译器为你加上了构造/析构的调用)。所以编译器还可以自行决定构造函数调用/返回
分配内存地址的顺序。这在编写多线程程序的时候可能会带来一些问题。关于这个问题最著名的是一个Singleton模式
的double-check,典型的double-check的Singleton代码是这样的:
volatile T* pInst = 0;
T* GetInstance()
{
if (NULL == pInst) {
lock();
if (NULL == pInst)
pInst = new T;
unlock();
}
return pInst;
}
// 上面的double-check代码在多线程环境下可能会出问题的。
为什么一定要运行析构函数?一个类对象所管理的资源,并不一定就只是内存资源啊。
有可能会管理文件描述符也就是文件资源、数据库连接之类的资源啊。
所谓RAII(Resource Acquisition Is Initialization),依赖的就是析构函数调用机制(局部对象超出
作用域自动析构;delete指针析构函数自动调用;全局/静态对象在main函数结束调用其析构函数保证
资源回收)。
RAII其实是比什么Java垃圾回收机制更好的东西。因为垃圾回收机制可没办法帮你管理数据库连接,而
RAII可以。关于RAII和资源管理,请参考《effective C++》.
回复 6# captivated
很感谢你,讲得很详细,终于弄清楚了
论坛里的高手好多,学习了