关于析构函数的问题,大虾们进来讲讲……

发布于 2022-10-15 08:46:11 字数 2028 浏览 25 评论 0

本帖最后由 zheguzai 于 2011-04-23 15:31 编辑

  1. #include <iostream>
  2. using namespace std;
  3. class A
  4. {
  5. public:
  6.         A();
  7.         ~A();
  8.         void set(int x)
  9.         {
  10.                 *i = x;
  11.         }
  12.         int get()
  13.         {
  14.                 return *i;
  15.         }
  16. private:
  17.         int *i;
  18. };
  19. A::A()
  20. {
  21.         cout<<"构造函数运行中……"<<endl;
  22.         i = new int (100);
  23.         cout<<*i<<endl;
  24.         cout<<i<<endl;
  25. }
  26. A::~A()
  27. {
  28.         cout<<"析构函数运行中……"<<endl;
  29.         delete i;
  30. }
  31. int main(void)
  32. {       
  33.         A *b;
  34.         b = new A;
  35.         cout<<b<<endl;
  36.         b->set(2);
  37.         cout<<b->get()<<endl;
  38.         delete b;
  39.         return 0;
  40. }

复制代码上面的代码是我在做实验的时候遇到的,我在堆上为对象开辟了一个空间,但是当我在函数结束时,使用delete来释放new所开辟的空间时,却调用了析构函数,delete不是已经将内存释放掉了么,为什么还会调用析构函数,析构函数的作用不也是释放对象的内存么。但是我要时不用deletel来释放,析构函数就不会执行,这一点我明白,因为在堆上分配的内存,系统是不会自己释放的,由程序员释放的。

我现在的问题是:我已经用delete来释放了在堆上开辟的空间,为什么还会调用析构函数。
请大虾讲讲,小弟不甚感激……

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

羞稚 2022-10-22 08:46:11

构造不是和析构成对出现吗?就跟new了后,就要delete一下,这根编译器有关系吧,我也有点含糊

放低过去 2022-10-22 08:46:11

调用了析构函数
让我感觉到蛋疼...
delete本来就是执行析构函数,回收内存.
这两个是两码事.

音盲 2022-10-22 08:46:11

却调用了析构函数
让我感觉到蛋疼...
delete本来就是执行析构函数,回收内存.
这两个是两码事.
egmkang 发表于 2011-04-23 16:19

    如果是一般的变量,比如,int *i= new int ;
这与的变量的在执行delete时是怎么释放内存的,这个又没析构函数,为什么在释放类的对象是就要调用析构函数

兔姬 2022-10-22 08:46:11

回复 4# zheguzai

内置类型的析构貌似什么事情也没做.

那支青花 2022-10-22 08:46:11

本帖最后由 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++》.

春庭雪 2022-10-22 08:46:11

回复 6# captivated

    很感谢你,讲得很详细,终于弄清楚了

弥繁 2022-10-22 08:46:11

论坛里的高手好多,学习了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文