C++基础入门教程(五):new和delete

   2015-06-26 0
核心提示:这篇文章主要介绍了C++基础入门教程(五):new和delete,本文讲解了动态分配内存、new和delete的配对、new、delete与reatin、release的关系、动态数组等内容,需要的朋友可以参考下

对于以前没有接触过C++,然后初次接触Cocos2d-x的朋友来说,可能对于内存管理方面会比较生疏。
也经常会因为内存问题导致各种小Bug,我也曾经写过一篇retain和release倒底怎么玩?,用来驾驭Cocos2d-x的对象引用和释放也算是足够了。
但,难道大家就不想知道retain和release背后的秘密吗?(小若:不想。)
 
没错,今天木头来带大家走进科学,走进世界,一起来探讨C++的new和delete。(小若:没兴趣。)
 
好,既然大家都等不及了,那就开始吧~

1.动态分配内存

我们都知道,像“int num = 10;”这样的语句,声明了一个num变量,这个变量是需要内存来放置(就像你的文档需要硬盘来放置)。
对于这样的普通变量,是在编译的时候就分配好内存的。
没错,就像你出生的时候就决定了是男是女了。(小若:这个比喻感觉一点关系都扯不上啊!而且,谁说出生就决定的?!)
 
通过声明指针变量可以指向这些预先被分配好的内存地址,但,我们的指针可不仅仅是为此而存在的。
指针还可以保存动态分配的内存的地址。
那么,怎么动态分配内存呢?没错,就是new,如下代码:

复制代码 代码如下:

// 可以这样
int *p = new int;
// 还可以这样
int *p = new int();
// 使用
*p = 20;
// 最后,要释放内存
delete p;

通过new后面跟着类型,就可以创建用于保存某种类型的内存空间,然后返回这个内存空间的地址。
它和直接声明int变量的区别是:
1.new出来的变量在运行程序的时候才会申请内存,普通int变量在编译的时候就分配了内存;
2.new出来的变量在不使用的时候需要释放掉,否则会内存泄露,使用delete即可释放指针指向的内存空间。

2.new和delete的配对

动态申请的内存,在不使用的时候,一定不要忘了释放掉,否则会造成内存泄露。
粗俗地说,不,通俗地说,动态申请了内存,其实只不过是告诉操作系统,这块内存归我了,其他人不能使用。
操作系统会乖乖地把你申请的那块内存给你用,如果你没有明确告诉它你不需要这块内存,则这内存永远都只能由你来使用。(当然,会有意外情况的,这个忽略)
 
所以,绝对不要忘记,在不使用的时候,要delete掉。
只要你new了一个变量,那就必须有对应的delete。

3.new、delete与reatin、release的关系

现在来看看Cocos2d-x内存管理,它就是为了让我们可以忽略new和delete的配对而诞生的。
谁没事想天天记着自己在哪里new了,又在哪里忘了delete呢?
 
所以,retain和release诞生了。
Cocos2d-x的大部分对象都是使用create函数创建的,而create函数里主要做了2件事情:
1.调用new创建新对象,也就是申请了内存
2.将对象添加到内存管理池(具体引用计数规则我就不说了)
 
而Cocos2d-x的内存管理主要做的一件事情是:
1.检查所以参与内存管理的对象,对那些需要释放的对象调用delete,释放内存
 
因此,我们不需要自己去维护new和delete,创建对象的时候,把对象交给内存管理就可以了。
如果我们不调用retain,那么,对象会在下一次内存管理检查的时候被释放(也就是下一帧)。
同时,addChild等函数都会主动调用一次对象的retain函数,所以被addChild的对象都不会被释放。
而在离开场景等操作时,对象也会被调用release函数,抵消一次retain的作用。
 
除非必要,否则,我们不需要主动调用retain函数,这就是“自动内存管理”的基本规则了。

4.动态数组

除了动态创建变量之外,数组也可以动态创建:int *nums = new int[10];
而对应的,释放动态数组有点特别:delete [] nums;
在delete后面需要加上一个[],代表释放的是数组。
 
动态数组的使用和一般数组差不多,当然,也有小差别:

复制代码 代码如下:

 int *nums = new int[3];
    nums[0] = 1;
    nums[1] = 2;
    nums[3] = 3;
    cout << nums[0];
    nums += 1;
    cout << nums[0];

第一次使用cout输出nums[0]时,输出的就是第一个元素的值:1。
但是,当调用了nums += 1时,指针nums已经指向了下一个地址,也就是nums[1]所在的地址。
所以,这时候再调用nums[0],输出的也是第一个元素的值,但此时的第一个元素已经不是1,而是2了。

5.结束

好了,关于new和delete暂时到这里。
但关于指针的初步介绍还有一小部分,下一篇再介绍吧~

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Aurelius vs mORMot vs EntityDAC Delphi 的
    Aurelius vs mORMot vs EntityDAC   Delphi 的 ORM框架:http://www.tmssoftware.com/site/aurelius.asp#product-buy-onlinehttps://synopse.info/fossil/wiki/Synopse+OpenSourcehttps://www.devart.com/entitydac/download.htmlkbmMW  http://www.compo
    02-09
  • 【Ruby】Mac gem的一些坑
    前言自上一次升级MacOS系统后出现jekyll无法构建的问题,当时处理半天。谁知道最近又升级了MacOS,荒废博客多时,今天吝啬写了一篇准备发布,构建报错,问题重新。还是记录下,以防下次升级出问题。问题描述安装jekyll静态博客需要在Ruby环境下运行,于是参照
    02-09
  • iOS oc 调用 swift
    如股票oc要调用swift里面的代码 需要包含固定这个头文件项目名称 LiqunSwiftDemo-Swift.h         #ProjectName#-Swift.h固定的写法swift 目的 是取代oc 但是 不会完全取代 只是前端的替换LiqunSwiftDemo-Swift 点进去 可以看到 所有的swift代码 都产生
    02-09
  • objective-c NSTimer 定时器
    -(void)initTimer{//时间间隔NSTimeInterval timeInterval =3.0 ;//定时器repeats 表示是否需要重复,NO为只重复一次NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(mobileAnimation) userInfo:nil
    02-09
  • Objective-C  日记③ 字符串
    Objective-C 日记③ 字符串
    一、创建字符串、类方法   公式创建NSString  +(id) stringWithFormat:(NSString *) format,……;eg:  NSString *height;  height=[NSString stringWithFormat:@"高度是: %d 长度: %d",10,20];得到的字符串:“高度是: 10 长度: 20” 注意:  省
    02-09
  • Objective-C KVC机制
    Objective-C KVC机制http://blog.csdn.net/omegayy/article/details/7381301全部推翻重写一个版本,这是我在公司内做技术分享的文档总结,对结构、条理做了更清晰的调整。 1.    基本概念MODEL主要是英文文档里面经常出现的一些概念,讲解一下,方便英文
    02-09
  • objective-c 加号 减号 - +
    “加号代表static”是错误的说法,可能跟你那样表达的人其实意思是:“前置加号的方法相当于Java 里面的静态方法”。在Oc中,方法分为类方法和实例方法。前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把
    02-09
  • Objective-C  日记①
    Objective-C 日记①
    1、Xcode的.m扩展名表示文件含有Object-C代码,C以.c文件,C++以.cpp文件2、头文件声明:C使用:#include,O-C使用#import(当然你也可以使用#include) 3、输出方式:  C:printf("",参数);  O-C:NSLog(@"",参数); 4、布尔类型  C:bool 具有true
    02-09
  • ASP.NET MVC 操作AD 获取域服务器当前用户姓
    #region 根据当前登录域账号 获取AD用户姓名和所在OU目录/// summary/// 根据当前登录域账号 获取AD用户姓名和所在OU目录/// /summary/// param name="searchUser"要搜索的当前用户名/param/// param name="paths"out返回该用户所在OU目录/param/// param nam
    02-09
  • swift和OC - 拆分数组 和 拆分字符串
    1. 拆分数组 /// 根据 数组 截取 指定个数返回 多个数组的集合func splitArray( array: [Date], withSubSize subSize: Int) - [[Date]] {//数组将被拆分成指定长度数组的个数let count = array.count% subSize == 0 ? (array.count/ subSize) : (array.count
    02-08
点击排行