精华内容
下载资源
问答
  • 析构函数调用

    2014-07-10 18:50:47
    最近调试代码遇到一个场景无法释放如果不释放数组等主动分配的,场景切换不会起作用,析构函数不会被调用

    最近调试代码遇到一个场景无法释放的问题。

    查找后发现,如果不释放数组等主动分配的,场景切换不会起作用,析构函数不会被调用。

    展开全文
  • 析构函数用于在事件结束后对对象的销毁, 不需要主动调用。 在创建对象后, 对于new出的对象需要调用delete语句进行销毁, 否则到程序结束后进行销毁 Problem Description 通过本题目的练习可以掌握创建普通对象...

    本题是关于析构函数和构造函数的调用:

    构造函数用于创建对象, 如果不在类内声明和定义的话, 在创建对象时编译器将自动创建一个空的构造函数, 系统将分配内存空间。析构函数用于在事件结束后对对象的销毁, 不需要主动调用。

    在创建对象后, 对于new出的对象需要调用delete语句进行销毁, 否则到程序结束后进行销毁


    Problem Description

    通过本题目的练习可以掌握创建普通对象、创建对象数组和动态创建和析构对象时调用构造函数和析构函数的时机;

    要求创建一个类A;类中仅包含构造函数和析构函数,按照程序的输出写出类的定义和主函数main中的代码。

    Input

     

    Output

     

    输出共有11行数据,分别如示例输出所示

    Sample Input

    Sample Output

    ----begin main---
    constructing an object of A
    constructing an object of A
    Destructing an object of A
    *******
    constructing an object of A
    constructing an object of A
    ----end main---
    Destructing an object of A
    Destructing an object of A
    Destructing an object of A

    Hint

     

    Source

    黄晶晶

     

    #include<iostream>
    using namespace std;
    
    class P
    {
    public:
        P()
        {
            cout<<"constructing an object of A"<<endl;
        }
        ~P()
        {
            cout<<"Destructing an object of A"<<endl;
        }
    };
    int main(void)
    {
        cout<<"----begin main---"<<endl;
        P test1;
        P *test2 = new P();
        delete test2;
        cout<<"*******"<<endl;
        P test3;
        P test4;
        cout<<"----end main---"<<endl;
        return 0;
    }
    

     

    展开全文
  • 析构函数何时被调用

    万次阅读 多人点赞 2018-07-26 15:42:45
    析构函数何时被调用 析构函数在下边3种情况时被调用: 对象生命周期结束,被销毁时; 主动调用delete ; 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。 第一种情况 #include &...

    析构函数何时被调用

    析构函数在下边3种情况时被调用:

    1. 对象生命周期结束,被销毁时;
    2. 主动调用delete ;
    3. 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

    第一种情况

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    void main()
    {
        A a;
    }

    运行结果:

    constructing A
    destructing A

    第二种情况

    如果是new的对象,即使离开了作用域也会一直存在,必须主动delete,否则只有在结束程序时才会执行析构。这里在说下内存泄漏,举个例子

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    void fun() 
    {
        A *a = new A();
    }
    
    int main() 
    {
        while (1) 
        {
            fun();
        }
        return 0;
    }

    当离开fun时,虽然离开了作用域,但用new动态开辟空间的对象是不会析构的,你可以观察任务管理器,看到内存一直在上升。但你在其他地方确无法使用a所开辟的空间,因为a这个指针是保存在栈上的,当离开作用域后就自动析构(或者说自动消失了),但它所在分配空间是分配在堆上的,只有主动析构或程序结束,才会释放空间,也就是丢失了这块空间的地址,无法操作这块空间了 。

    第三种情况

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    class C
    {
    public:
        C()
        {
            cout << "constructing C" << endl;
        }
        ~C()
        {
            cout << "destructing C" << endl;
        }
    private:
        int c;
    };
    
    class B : public A
    {
    public:
        B()
        {
            cout << "constructing B" << endl;
        }
        ~B()
        {
            cout << "destructing B" << endl;
        }
    private:
        int b;
        C c;
    };
    
    void main()
    {
        B b;
    }

    运行结果:

    constructing A
    constructing C
    constructing B
    destructing B
    destructing C
    destructing A

    B的析构函数调用之后,又调用了B的成员c的析构函数 。

    若将上边的代码中的main()函数内容改成

     A* a = new B;
    
     delete a;

    我们知道,这将不会调用class B的析构函数不会被调用,所以class C的析构函数也不会被调用。

    运行结果:

    constructing A
    constructing C
    constructing B
    destructing A

    若将class A中的析构函数声明为虚函数 ,这时class B的析构函数也会被调用,例如:

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        A()
        {
            cout << "constructing A" << endl;
        }
        virtual ~A()
        {
            cout << "destructing A" << endl;
        }
    private:
        int a;
    };
    
    class C
    {
    public:
        C()
        {
            cout << "constructing C" << endl;
        }
        ~C()
        {
            cout << "destructing C" << endl;
        }
    private:
        int c;
    };
    
    class B : public A
    {
    public:
        B()
        {
            cout << "constructing B" << endl;
        }
        ~B()
        {
            cout << "destructing B" << endl;
        }
    private:
        int b;
        C c;
    };
    
    void main()
    {
        A* a = new B;
    
        delete a;
    }

    运行结果:

    constructing A
    constructing C
    constructing B
    destructing B
    destructing C
    destructing A

    此文章参考了:https://blog.csdn.net/weizhee/article/details/562833

    展开全文
  • C++主动调用析构函数分析

    千次阅读 2017-12-05 19:41:49
    C++编程规范中都不支持显示的调用析构函数,部分文章中甚至说明析构函数是不能显示调用的,然而执行如下类似的操作编译器并不会报错,而且会调用成功。 pa->~A(); 显示调用析构函数有会引起什么问题?为什么C++标准...
    1、  关于主动调用析构函数;
    

    C++编程规范中都不支持显示的调用析构函数,部分文章中甚至说明析构函数是不能显示调用的,然而执行如下类似的操作编译器并不会报错,而且会调用成功。

    pa->~A();

    我们先来看看这样的操作会有哪些副作用,然后再讨论存在的意义;

    1.       如果在析构函数中显示地释放了堆上的内存,显示调用析构函数会存在重复释放内存错误,例子如下:

    class A

    {

            char *a;

    public:

            A(){a =(char *)malloc(4);}

            ~A()

            {

                   free(a);

                   printf(“Adeconstructor\n”);

            }

    };

    int main()

    {

            A a;

            a.~A();

            return0;

    }

    2.       显示的调用析构函数相当于执行了析构函数内容(包括子类析构函数),但是并没有释放内存,也没有摧毁对象;上述的例子可以理解为a对象占用了char *大小的栈内存,占用了4个字节的堆内存,堆内存通过构造函数申请,通过析构函数释放;显示的调用析构函数执行了析构函数,释放掉了堆上的内存,但是并不会释放栈上内存。

    3.       使用new操作符的情况有写不同,new操作符可以考虑为两个阶段。

    a.  在堆上申请对象本身成员所占内存;

    b.  执行构造函数。

    考虑如下例子:

    class A

    {

            char *a;

    public:

            A(){a =(char *)malloc(4);}

            ~A()

            {

                   free(a);

                   printf(“Adeconstructor\n”);

            }

    };

    int main()

    {

            A *a =new A();

            a->~A();

            return0;

    }

    显然此时编译器不会隐式调用析构函数,所以不会出现重复释放的问题,但是由于a->~A()只会执行析构函数,a指针本身所占的内存不会被释放掉,所以会造成内存泄漏。

     

    由以上的分析可知,显示调用析构函数不但不会带来任何好处,还会造成很多奇怪、难以分析的问题,这也是不推荐使用的原因,为什么C++标准不禁止呢?来看一下关于placementnew的用法。

    placement new是operator new的一个重载版本;所谓placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可。

    例子如下:

    struct A {…};

    struct B {…};

     

    A* pa = new A;

    pa->~A();

    B* pb = new (pa) B;//placement new

    以上例子必须要求sizeof(A)>=sizeof(B)。B* pb = new (pa) B并不会申请内存,只是在原来A对象的位置上生成B的对象。

     

    更普遍的使用方法如下:

    class A{

           …

    public:

           show();

    };

    1)分配内存

    char* buff = new char[ sizeof(A) *N+sizeof(int)) ];

    memset( buff, 0, sizeof(A)*N +sizeof(int));

     

    2)构建对象

    A* pa = new (buff)A;

     

    3)使用对象

    pa->show();

     

    4)析构对象,显式的调用类的析构函数。

    pa->~A();

     

    5)销毁内存

    delete [] buff;

     

    对于buff这块内存可以反复使用,只要重复2)、3)、4)步骤即可。在C++标准中,对于placementoperator new []有如下的说明:placementoperator new[] needs implementation-defined amount of additional storage tosave a size of array. 所以我们必须申请比原始对象大小多出sizeof(int)个字节来存放对象的个数,或者说数组的大小。

    对于效率和容错要求比较高的程序来说placement new是很有用的:

    1)  placement new能够有效的解决内存碎片的问题;

    2)  malloc、new等申请内存有失败的可能,对有些程序来说是不允许的,而placementnew可以做到;

    3)  placement new不需要执行申请内存的过程,速度更快;

     

    C++标准STL就有使用placement new的情况,不过不是在特殊情况下比如自己编写高效率库、需要自己管理内存池时不推荐使用placement new。

    展开全文
  • 析构函数何时被调用 析构函数在下边3种情况时被调用: 对象生命周期结束,被销毁时; 主动调用delete ;(推荐学习:PHP编程从入门到精通) 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用...
  • 析构函数

    2020-06-14 15:37:58
    主动调用析构函数并不会摧毁对象,反而容易造成多次delete内存的情况,所以不要主动调用析构函数。 函数运行结束时,在退栈时会摧毁对象。但new出来的对象,由于保存在堆区,不会随着函数退栈而释放,需要主动delete...
  • #include <iostream> #include <list> class destructor_test{ public: ~destructor_test(){ std::cout << "~destructor_test" << std::endl; ...class test{...
  • C++之虚析构函数

    2020-01-31 13:35:11
    文章目录析构函数析构函数 析构函数 我们知道,构造函数是用来在...构造和析构不需要主动调用,由系统自动调用,当类中没有析构函数时,系统会自动生成,类的析构函数主要是为了释放内存资源,析构函数如果不被...
  • 析构函数(C++)

    2020-03-28 10:39:27
    析构函数(C++) 1.析构函数是对象被销毁时,...4.析构函数有2种方式调用,一个是主动调用delete,另一个是根据RAII的规则,在对象的生命周期结束时自动析构。 5.析构函数:在类中声明的一种成员函数 ①析构函数与...
  • 析构函数的定义

    千次阅读 2017-11-02 15:24:21
    首先来到一个问题,什么是析构函数,在《C++语言程序设计》...他与构造函数的作用几乎正好相反,用来完成对象呗删除前的一些清理工作,是在对象的生存期即将结束的时刻被自动调用的(有特殊情况是可以主动调用析构函数
  • 析构函数 (C++)

    2018-08-23 09:48:00
    最近发现自己对析构函数的认知有一定的问题,因为之前有在使用placement new时主动调用对象的析构函数,所以觉得析构函数只是个普通的成员函数,调用的时候只会执行自己方法体内的代码内容,而回收内存则是由于生命...
  • 下面的代码是矩阵类的一部分析构函数的语句,在稀疏矩阵的析构中显式调用了对象m_matrix的析构函数,开始看似没问题,但是程序执行后总是有内存泄露...//在这里主动调用了对象的析构函数}this->m_matrix = NULL;}
  • 私有析构函数

    千次阅读 2012-02-28 18:02:22
    那么我们可以知道,要实现资源回收(不管是主动的还是被动的)都要调用函数,而一旦将析构函数设置为私有的,肯定就会限制资源的回收的。 而设置的这种限制可以让我们做很多其他的事情,如要想析构就必须
  • 析构函数,在using结束时,会调用;所以,一般用在 事务、Session等 需主动声明,方法结束后 要调用 Dispose的地方; Dispose,只有在 释放内存时才会调用 (并不是出了局域变量的作用域就会调用); 就算...
  • C++的析构函数

    2015-01-24 17:01:09
    1• 与类名同,但名称前有一个波浪号~ ...5• 一个对象的析构函数调用一次,但语法上允许多次调用 6• 默认析构函数  何时需要自定义析构呢? // // main.cpp // 析构函数 // // Created by 06
  • 3.1 more effective c++提出析构函数不能抛出异常的两点理由 4.如何处理析构函数中的异常? 4.1 析构函数内部消化异常 4.2主动关闭程序 4.3把可能抛出异常的代码移出析构函数 引子 先看一个程序,会输出什么?...
  • c++理解析构函数

    2019-04-27 11:21:00
    析构函数有2种方式调用,一个是主动调用delete,另一个是根据RAII的规则,在对象的生命周期结束时自动析构。第一点没什么好说的,就简单讲下第二点。 对象的生命周期不等于是程序的生命周期,一般我们所谓的生命...
  • 出处:http://blog.csdn.net/linpengbin/article/details/50810584我们都知道构造函数不能为虚函数,而基类的析构函数一般都要定义为虚函数。今天重新复习了一下,特在此记载,以便查找。构造函数不能为虚函数主要有...
  • 析构函数 Destructor

    2011-12-05 19:07:00
     调用对象的析构函数来回收其所占用的存储空间(对象,动态内存等)和资源(信号量,互斥锁等)。 一 普通虚构函数 class ConcreateObject: public object{public: ~ConcreateObject();};//使用 范围{ Con...
  • 构造函数与析构函数

    2018-01-24 23:16:00
    构造函数基本不主动调用.系统调用.如果没有构造函数无法构造对象,如果没有提供构造函数,系统会自动给生成一个默认的构造函数. 注意: 默认的构造函数没有参数. 调用时机: 当需要创建对象的时候 在构建对象的时候,...
  • 我们都知道构造函数不能为虚函数,而基类的析构函数一般都要定义为虚函数。今天重新复习了一下,特在此记载,以便查找。构造函数不能为虚函数主要有以下两点1、必要性分析: 当定义派生类对象时,它会主动依次调用...
  • //注:在不涉及类指针操作时,基类的析构和构造不必为virtual虚函数02 基类指针指向继承类对象,此时主动释放基类指针指向的对象时,会先调用基类的析构函数,紧接着判断该此是否为虚函数。如果是,则会调用继承类的...
  • 因为析构函数经常被自己主动调用,在析构函数中抛出的异常往往会难以捕获,引发程序非正常退出或没有定义行为。 比如,对象数组被析构时。会抛出多于一个的异常,然而同一时候存在的异常在C++标准中是禁止的, 因此...

空空如也

空空如也

1 2 3 4 5
收藏数 84
精华内容 33
关键字:

析构函数主动调用