zoukankan      html  css  js  c++  java
  • Cocos2d-x开发中C++内存管理

    由于开始并没有介绍C++语言,C++的内存管理当然也没进行任何的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识。
    C++内存管理非常复杂,如果完全地系统地介绍可能需要一本书的篇幅才能解释清楚。这里只给大家介绍C++内存管理最为基本的用法。


    内存分配区域
    创建对象需要两个步骤:第一步,为对象分配内存,第二步,调用构造函数初始化内存。在第一步中对象分配内存时候,我们可以选择几个不同的分配区域,这几个区域如下:
    栈区域分配。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。由处理器自动分配和释放,用来存放函数的参数值和局部变量的值等。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
    堆区域分配。从堆上分配,亦称动态内存分配。由开发人员分配释放,如果不释放,程序结束时由操作系统回收。 程序在运行的时候用malloc或new申请任意多少的内存,开发人员自己负责在何时用free或delete释放内存。动态内存的生存期由开发人员决定,使用非常灵活,但问题也最多。
    在静态存储区域分配。这个内存空间在程序的整个运行期间都存在,内存在程序编译的时候就已经分配好。它可以分配全局变量和静态变量。


    动态内存分配
    动态内存分配最为灵活但是问题也很多,我们重点介绍动态内存分配。动态内存使用malloc或new分配内存,使用free或delete释放内存。其中malloc和free是成对的,new和delete是成对的。
    1、malloc和free使用
    malloc和free是C/C++语言的标准库函数,主要是在C中使用。使用malloc创建对象,不会自动调用构造函数初始化内存。使用free释放对象,不会自动调用析构函数清除内存。
    使用malloc和free分配和释放内存的实例代码如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include <iostream>  
    2.   
    3.   
    4. using namespace std;  
    5.   
    6.   
    7. class MyObject    
    8. {    
    9. public :   
    10.     MyObject(){                                                             ①  
    11.         cout << "call constructor." <endl;   
    12.     }    
    13.       
    14.     ~MyObject(){                                                            ②  
    15.         cout << "call destructor." <endl;   
    16.     }    
    17.   
    18.   
    19.     void initialize(){                                                      ③  
    20.         cout << "call initialization." <endl;   
    21.     }    
    22.       
    23.     void destroy(){                                                         ④  
    24.         cout << "call destroy." <endl;   
    25.     }    
    26. };    
    27.   
    28.   
    29. int main(){  
    30.   
    31.   
    32.     MyObject *obj = (MyObject *)malloc(sizeof(MyObject)); // 申请动态内存                 ⑤  
    33.     obj->initialize();                                                       ⑥  
    34.       
    35.     //TODO  
    36.       
    37.     obj->destroy();                                                          ⑦  
    38.     free(obj);                                                              ⑧  
    39.     obj = NULL;  
    40.   
    41.   
    42.     return 0;  
    43. }  



    上述代码创建了声明了MyObject类,其中第①行代码是声明构造函数,第②行代码是声明析构函数。第③行代码是声明初始化函数void initialize()在使用malloc分配内存时候不能调用构造函数,通过调用该函数初始化该对象。第④行代码是声明清除函数void destroy()在使用free释放对象内存时候,通过调用该函数清除该对象的一些资源。
    第⑤~⑧行是调用MyObject类进行测试,其中第⑤行代码MyObject *obj = (MyObject *)malloc(sizeof(MyObject))是使用malloc函数分配内存,使用该函数需要指定对象的长度,还有malloc函数返回值是void*,由于C++不允许void*赋值给其它指针,所以需要强制类型转换。由于构造函数不能显式调用,所以需要第⑥行代码是初始化对象。
    第⑧行代码free(obj)是释放obj对象内存。在释放对象内存之前,我们在第⑦行代码obj->destroy()是在释放对象内存之前调用,清除该对象的一些资源,它的作用相当于析构函数。但是真正的析构函数~MyObject()并没有调用。
    运行结果如下:
    call initialization.
    call destroy.


    2、new和delete使用
    与malloc和free不同,new和delete不是函数库,而是C++的运算符。new运算符能够完成创建对象所有步骤(即:第一步,为对象分配内存,第二步,调用构造函数初始化内存),它也会调用构造函数。实例代码:
    MyObject *obj = new MyObject();
    构造函数可以重载,根据用户传递的参数列表,决定调用哪个构造函数进行初始化对象。
    new运算符反操作运算符是delete,delete先调用析构函数,再释放内存。实例代码:
    delete obj;
    obj是对象指针,obj只能释放new创建的对象,不能释放有malloc创建的。而且采用delete释放后的对象指针,需要obj=NULL以防止“野指针”。
    提示  一种情况是,指针变量没有被初始化,它的指向是随机的,它会乱指一气,并不是为NULL。如果使用if语句判断,则认为是有效指针。另外情况是,指针变量被free或者delete之后,它们只是把指针所指的内存给释放掉,但并没有把指针本身清除,此时指针指向的就是“垃圾”内存。如果使用if语句判断,也会认为是有效指针。“野指针”是很危险的,良好的编程习惯是,这两种情况下都需要将指针设置为NULL,这是避免“野指针”的唯一方法。
    使用new和delete分配和释放内存的实例代码如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include <iostream>  
    2.   
    3.   
    4. using namespace std;  
    5.   
    6.   
    7. class MyObject    
    8. {    
    9. public :   
    10.     MyObject(){  
    11.         cout << "call constructor." <endl;   
    12.     }    
    13.       
    14.     ~MyObject(){   
    15.         cout << "call destructor." <endl;   
    16.     }    
    17.   
    18.   
    19.     void initialize(){   
    20.         cout << "call initialization." <endl;   
    21.     }    
    22.       
    23.     void destroy(){   
    24.         cout << "call destroy." <endl;   
    25.     }    
    26. };    
    27.   
    28.   
    29. int main(){  
    30.   
    31.   
    32.     MyObject *obj = new MyObject(); // 申请动态内存    
    33.   
    34.   
    35.     //TODO  
    36.   
    37.   
    38.     delete obj;  
    39.     obj = NULL;  
    40.   
    41.   
    42.     return 0;  
    43. }   



    同样是MyObject类,采用是new分配内存,delete释放内存。程序运行会调用构造函数和析构函数。运行结果如下:
    call constructor.

    call destructor.

    更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
    本书交流讨论网站:http://www.cocoagame.net
    更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
    欢迎加入Cocos2d-x技术讨论群:257760386


    《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

    京东:http://item.jd.com/11584534.html

    亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

    当当:http://product.dangdang.com/23606265.html

    互动出版网:http://product.china-pub.com/3770734

    《Cocos2d-x实战 C++卷》源码及样章下载地址:

    源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1 

    样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

    欢迎关注智捷iOS课堂微信公共平台
  • 相关阅读:
    Redis认识
    常见注解和LambdaQueryWrapper
    微信开发思路和一些文档
    安全框架
    学习:Token
    javascript中对象的创建-原型模式1
    开发常用工具
    【java爬虫--1】Htmlunit+Jsoup解析非静态页面爬取图片
    【java爬虫--2】将批量图片地址转成pdf文件
    文本文件按行去重,有序输出
  • 原文地址:https://www.cnblogs.com/iOS-Blog/p/4070174.html
Copyright © 2011-2022 走看看