C/C++动态内存管理以及虚函数

Posted on 2019-12-30 11:22  yacbo  阅读(198)  评论(0编辑  收藏  举报

C/C++动态内存管理

C语言动态内存管理
申请内存的方式

栈上(静态内存管理)
1.生命周期随栈帧。栈帧结束,内存归还给操作系统,无需程序猿管理。

2.空间开辟的大小固定,申请数组时数组的大小必须指定。他内存在编译时期就已经分配好。

3.程序在运行时期不能进行内存申请。而这种情况在编程中又很常见。所以就需要动态内存管理。

堆上(动态内存管理)
1.生命周期由程序猿管理。需要手动申请手动释放。且必须释放,否则就会造成内存泄露

2.开辟空间大小由程序猿指定,更灵活。空间分配在程序运行期间分配。

对比:栈上申请内存比较省心,规规矩矩。缺乏灵活性,而堆上申请内存更为灵活。但是灵活也就意味着风险。如果只申请,不释放,就会造成内存泄露。释放的内存的申请的内存要匹配。   

  
  int
*p = (int *)malloc(20*sizeof(int)); int *pp = (int *)calloc(20, sizeof(int)); int i; printf("malloc申请的空间值:\n\n"); for ( i=0 ; i < 20; i++) { printf("%d ", *p++); } printf("\n\n"); printf("calloc申请的空间的值:\n\n"); for ( i=0 ; i < 20; i++) { printf("%d ", *pp++); }   free(p);   free(pp);

 

class Array
{
    public:
        Array(size_t size=10)
            :_size(size)
            ,_a(0)
    {
        cout<<"Array(size_t size)"<<endl;
        if(size>0)
        {
            _a=new int[size];
        }
    }
        ~Array()
        {
            cout<<"~Array()"<<endl;
            if(_a)
            {
                delete[]_a;
                _a=0;
                _size=0;
            }

        }
    private:
        int * _a;
        size_t _size;
};
int main()
{
    Array* p1=new Array;
    delete p1;
    Array* p2=new Array[5];
    delete []p2;
    return 0;

}

 

C++杂谈 为什么需要虚析构函数

①虚函数:在类的成员函数前面加virtual关键字的函数;
一般把虚函数定义在public区,方便在主函数中调用
如果一个类有一个虚函数,则该类就有一个虚函数列表,所有该类的对象都共享这个虚函数表;(QT调试过程中显示的是vptr)
如果一个类有一个或者一个以上的虚函数,则该类有且只有一张虚函数表,每个类都只有一个虚函数表,该类的所有对象都共享这张虚函数表
子类的虚函数表中子类的虚函数覆盖父类的虚函数的情况,当子类将父类的虚函数override时,就覆盖了父类的虚函数;

满足override的条件:函数名相同,函数的返回值相同,形参列表相同;

纯虚函数:形式为 virtual void fun1() = 0
纯虚函数不需要实现,原因是不会被调用到;

抽象基类:至少有一个纯虚函数的类;
抽象基类不能产生该类的对象,但可以有该类的指针或引用;
在子类中必须将父类的纯虚函数实现,不然该子类也是抽象基类;

当一个类有子类时,该类的析构函数必须是虚函数,原因:会有资源释放不完全的情况;

对象销毁时只调用了父类的析构函数。如果这时子类的析构函数中有关于内存释放的操作,将会造成内存泄露。所以需要给父类的析构函数加上virtual。

 

 

刚开始的时候对于这个问题我一直搞不明白,总觉得这是多此一举,后来上网查资料看到了一些人的解释明白了为什么要这样,用一个例子来解释应该最好理解了:

你写了一个飞机游戏,画面里出现什么类型飞机是随机决定的,你的代码里也就不可能用一个具体飞机类型来操作。 所以,往往是随机生成各种类型飞机,他们有共同的父类,你的代码就可以用父类指针来控制行为。比如中弹后的能量损失多少之类,每种飞机可能不同。

 

 

Copyright © 2024 yacbo
Powered by .NET 8.0 on Kubernetes