《Cocos2dx面试题》 |
版本node |
做者程序员 |
参与者面试 |
完成日期算法 |
备注sql |
Cocos2dx_JobView_V01_1.0数据库 |
严立钻编程 |
|
2018.08.22windows |
|
|
|
|
|
|
|
|
|
|
|
##《Cocos2dx面试题》发布说明:设计模式
++++“Cocos2dx”是2014年比较流行的2D游戏引擎,固然也有3D版本,最近一直在作Unity3d相关的工做,因此对于Cocos2dx没有特别关注,可是做为一款优秀的游戏引擎,仍是值得咱们参考学习的;数组
++++“Cocos2dx面试题”:不只仅包含Cocos2dx内容,还包括相关C++、Lua相关知识点;经过这篇博文,让你们熟悉一下Cocos2dx面试相关内容;
##《Unity面试题》目录:
#第一篇:一场模拟面试
#第二篇:Cocos2dx和C++知识点
#第一篇:一场模拟面试 |
#第一篇:一场模拟面试
++++立钻哥哥:因为整理Cocos2dx的时间比较仓促,也没有特别在乎章节排版,直接利用一场模拟面试来揭开Cocos2dx剖析之路;
++++A.一、请列举标准C/C++的基本变量类型(例如:int),以及它们的字节长度(2分)
++++A.二、请用#define语句完成如下需求(4分)
++++A.三、请计算sizeof的值(5分)
++++A.四、在VC6下定义以下结构(4分)
++++A.五、头文件中的ifndef/define/endif 干什么用?(2分)
++++A.六、简述进程和线程的区别?(2分)
++++A.七、多线程编程时,线程间同步的方法有哪些?(2分)
++++A.八、#include<filename.h>和#include “filename.h”有什么区别?(2分)
++++A.九、有关内存的思考题?(8分)
++++A.十、请写出下面代码的输出结果?(8分)
++++A.十一、请写出下面代码的输出结果?(8分)
++++A.十二、下面一段代码会产生内存泄露,请问如何修改能避免内存泄露? 并简述理由?(8分)
++++A.1三、编写strcpy()函数?(10分)
++++A.1四、以下两种写法有什么区别?(5分)
++++A.1五、关键字static在C语言中的做用?(5分)
++++A.1六、C++是安全类型的语言吗?(2分)
++++A.1七、一个空类的大小,并解释?(2分)
++++A.1八、面向对象与面向过程?(2分)
++++A.1九、引用与指针?(2分)
++++A.20、多态?(2分)
++++A.2一、深度优先遍历与广度优先遍历?(2分)
++++A.2二、内存对齐问题?(2分)
++++A.2三、写一个链表逆序?(2分)
++++A.2四、写一个根据几率随机掉装备的函数?(2分)
++++A.2五、四人过桥问题?(2分)
++++A.2六、输入任意四个0~9中的数,经过+-*/()运算获得24,写算法或伪代码?
##A.一、请列举标准C/C++的基本变量类型(例如:int),以及它们的字节长度(2分) |
++A.一、请列举标准C/C++的基本变量类型(例如:int),以及它们的字节长度(2分)
++++立钻哥哥:
bool |
1个字节[*] |
||
char |
1个字节[*] |
||
short |
2个字节[**] |
||
int |
4个字节[****] |
||
float |
4个字节[****] |
||
long |
4个字节[****] |
||
double |
8个字节[********] |
||
#include <stdio.h>
int main(void ){ printf(“int = %d\n”, sizeof(short int)); printf(“int = %d\n”, sizeof(int)); printf(“long int = %d\n”, sizeof(long int)); printf(“char=%d\n”, sizeof(char)); printf(“float=%d\n”, sizeof(float)); printf(“double=%d\n”, sizeof(double)); } //立钻哥哥:int main(void){} |
|||
16位系统 |
long是4字节 |
int是2字节 |
|
32位系统 |
long是4字节 |
int是4字节 |
|
64位系统 |
long是8字节 |
int是4字节 |
##A.二、请用#define语句完成如下需求(4分) |
++A.二、请用#define语句完成如下需求(4分)
--A、定义一个常量MSOFDAY,表示1天多少毫秒?
--B、定义一个宏x(a),计算数组元素的个数,a为数组变量名称,x(a)返回数组元素个数?
++++立钻哥哥:
#define MSOFDAY 1*24*60*60*1000 #define x(a) sizeof(a)/sizeof(*a) |
##A.三、请计算sizeof的值(5分) |
++A.三、请计算sizeof的值(5分)
char str[] = “Hello”;
char *p = str;
int n = 10;
请计算:
===>sizeof(str) =
===>sizeof(p) =
===>sizeof(n) =
++++立钻哥哥:
char str[] = “Hello”; char *p = str; int n = 10; ===>sizeof(str) = 6; ===>sizeof(p) = 4; ===>sizeof(n) = 4; |
++A.3.一、
void Func(char str[100]){
请计算:
sizeof(str) =
}
++++立钻哥哥:
void Func(char str[100]){ sizeof(str) = 4; } |
++A.3.二、
void *p = malloc(100);
请计算:
sizeof(p) =
void *p = malloc(100); sizeof(p) = 4; |
##A.四、在VC6下定义以下结构(4分) |
++A.四、在VC6下定义以下结构(4分)
typeof struct{
char c1;
char c2;
long n;
}stru;
请问sizeof(stru)等于多少?
并说明理由?
++++立钻哥哥:8字节;
++++结构体采起的内存分配原则是:四字节对齐;
++++CPU在读取内存数据的时候:4字节对齐会取得更快的速度;
++++1字节8位,4字节正好32位;
++++而32位机器的寄存器,地址什么的都是32位,正好一次处理就完成;
++++补充:若是double n ===>立钻哥哥:12字节;
##A.五、头文件中的ifndef/define/endif 干什么用?(2分) |
++A.五、头文件中的ifndef/define/endif 干什么用?(2分)
++++立钻哥哥:定义并防止重复定义;
++++能够在其中声明函数;
##A.六、简述进程和线程的区别?(2分) |
++A.六、简述进程和线程的区别?(2分)
++++立钻哥哥:进程是系统分配内存的最小开销,一个进程能够有多个线程,线程依附于进程而存在;线程能够共享进程中的局部变量;
++++一个进程内的全部线程共享同一全局内存空间;(这使得线程间很容易共享信息,可是这种容易性也会带来了同步问题);
++++进程:是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单元; ++++线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位; ++++线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源; ++++一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行; |
++++进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性; ++++进程和线程的区别在于:简而言之,一个程序至少有一个进程,一个进程至少有一个线程; ++++线程的划分尺度小于进程,使得多线程程序的并发性高; ++++进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率; ++++线程在执行过程当中与进程仍是有区别的:每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口;可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制; |
++++进程和线程的区别: --A、地址空间和其余资源:进程间相互独立,同一进程的各线程间共享;某进程内的线程在其它进程不可见; --B、通讯:进程间通讯IPC:线程间能够直接读写进程数据段(如全局变量)来进行通讯; --C、调度和切换:线程上下文切换比进程上下文切换要快得多; |
##A.七、多线程编程时,线程间同步的方法有哪些?(2分) |
++A.七、多线程编程时,线程间同步的方法有哪些?(2分)
++++立钻哥哥:互斥量、信号量、事件、临界区;
++++Windows中的4种线程同步技术:
--A、Events(事件):CEvent:做为标志在线程之间的传递信号;简单地说:相似一个布尔型变量的开关做用;
--B、Critical Sections(临界段):CCriticalSection:在进程中做为关键字以得到对“共享资源”的访问;
--C、Mutexes(互斥量):CMutex:与临界段的工做方式类似,只是该对象能够用于多进程中的线程同步,而不是用于单进程中;
--D、Semaphores(信号量):CSemaphore:在给定的限制条件下,容许多个进程同时访问共享资源;
++Linux进程通信方式: ++++立钻哥哥:管道、共享内存、消息队列、信号、socket等; ++++IPC(Interprocess Communication,IPC):进程间通讯: --A、消息传递:(管道、FIFO(有名管道)、消息队列); --B、同步:(互斥量、条件变量、读写锁、信号量); --C、共享内存区:(匿名共享内存区、有名共享内存区); --D、进程调用:(Solaris门、SunRPC); |
++Linux下如何建立线程: ==>pthread_create(&id, NULL, move, stack); ==>pthread_join(pthread_t tid, void** status); |
##A.八、#include<filename.h>和#include “filename.h”有什么区别?(2分) |
++A.八、#include<filename.h>和#include “filename.h”有什么区别?(2分)
++++立钻哥哥:
++++<filename.h>:编译器从开发环境设置的路径开始搜索filename.h;
++++“filename.h”:编译器从用户的工做路径开始搜索filename.h;
##A.九、有关内存的思考题?(8分) |
++A.九、有关内存的思考题?(8分)
++++立钻哥哥:
++请问运行Test函数会有什么样的结果? void GetMemory(char* p){ p = (char*)malloc(100); }
void Test(void){ char* str = NULL; GetMemory(str); strcpy(str, “hello world”); printf(str); } ++++立钻哥哥:会中断,由于str并无提早分配内存; ++++程序崩溃:由于GetMemory并不能传递动态内存,Test函数中str一直都是NULL,strcpy(str, “helloworld”);,将使程序崩溃;
|
++请问运行Test函数会有什么样的结果? char* GetMemory(void){ char p[] = “helloword”; return p; }
void Test(void){ char* str = NULL; str = GetMemory(); printf(str); } ++++立钻哥哥:程序报错,由于栈区分配空间已经被释放; ++++多是乱码:由于GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,但其原有的内容已经被清除,新内容不可知;
|
++请问运行Test函数会有什么样的结果? void GetMemory(char** p, int num){ *p = (char*)malloc(num); }
void Test(void){ char* str = NULL; GetMemory(&str, 100); strcpy(str, “hello”); printf(str); } ++++立钻哥哥:hello; ++++可以输出“hello”,内存泄露;
|
++请问运行Test函数会有什么样的结果? void Test(void){ char* str = (char*)malloc(100); strcpy(str, “hello”); free(str);
if(str != NULL){ strcpy(str, “world”); print(str); } } ++++立钻哥哥:world; ++++篡改动态内存区的内容,后果难以预料,很是危险,由于free(str)以后,str成为野指针,if(str != NULL)语句不起做用;
|
##A.十、请写出下面代码的输出结果?(8分) |
++A.十、请写出下面代码的输出结果?(8分)
class MyClass{ public: MyClass(){ printf(“Construct MyClass\n”); };
void SayHello(void){ printf(“Hello\n”); } };
void TestMyClass(void){ static MyClass MyClassForTesting; MyClassForTesting.SayHello(); }
int main(void){ TestMyClass(); TestMyClass();
return 0; } |
++++立钻哥哥:construct MyClass Hello Hello
++++补充拓展:总结static的应用和做用:
--A、函数体内static变量的做用范围为该函数体,不一样于auto变量,该变量的内存只被分配一次,所以其值在下次调用的时候仍然维持上次的值;
--B、在模块内的static全局变量能够被模块内全部函数访问,但不能被模块外其余函数访问;
--C、在模块内的static函数只能够被这一模块内的其余函数调用,这个函数的使用范围被限制在声明它的类模块中;
--D、在类中的static成员变量属于整个类所拥有,对类的全部对象只有一份拷贝;
--E、在类中的static成员函数属于整个类所拥有,这个函数不接受this指针,于是只能访问类的static成员变量;
##A.十一、请写出下面代码的输出结果?(8分) |
++A.十一、请写出下面代码的输出结果?(8分)
class Base{ public: Base(){}; ~Base(){};
virtual void WhoAmI(void){ printf(“Base\n”); };
void OutPutMessage(void){ WhoAmI(); }; };
class Derived : public Base{ public: Derived(){}; ~Derived(){};
virtual void WhoAmI(void){ printf(“Derived\n”); }; };
int main(void){ Derived D; Base *pB = &D; D.OutputMessage(); pB->OutputMessage();
return 0; } |
++++立钻哥哥:Derived Derived
##A.十二、下面一段代码会产生内存泄露,请问如何修改能避免内存泄露? 并简述理由?(8分) |
++A.十二、下面一段代码会产生内存泄露,请问如何修改能避免内存泄露? 并简述理由?(8分)
class Base{ public: Base(){ m_piPtr = new int; } ~Base(){ delete m_piPtr; }
private: int *m_piPtr; };
class Derived : public Base{ public: Derived(){ m_plDerived = new long; } ~Derived(){ delete m_plDerived; }
private: long* m_plDerived; };
int main(void){ Base* p = new Derived; delete p;
return 0; } |
++++立钻哥哥: virtual ~Base(){ delete m_piPtr; }
++++拓展说明1:C++中为何基类析构函数通常要声明为虚函数:
--1.A、类析构函数要声明为虚函数:这样派生类调用析构函数才能层层回调,释放资源;(这也是虚函数的做用:提供回调的指针)
++++拓展说明2:基类的析构函数为何是虚函数:
--2.A、通常状况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会形成内存泄露;
--2.B、当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用;
++++拓展说明3:并非要把全部类的析构函数都写成虚函数:
--3.A、由于当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增长类的存储空间;因此,只有当一个类被用来做为基类的时候,才把析构函数写成虚函数;
++补充:《EffectiveC++》条款07:
++++立钻哥哥:条款07:为多态基类声明virtual析构函数;
++++析构函数的运做方式是:最深沉派生的那个class其析构函数最早被调用,而后是其每个base class的析构函数被调用;
++++请记住:polymorphic(带多态性质的)base classes应该声明一个virtual析构函数;
--若是class带有任何virtual函数,它就应该拥有一个virtual析构函数;
++++Classes的设计目的:若是不是做为base classes使用,或不是为了具有多态性(polymorphically),就不应声明virtual析构函数;
##A.1三、编写strcpy()函数?(10分) |
++A.1三、编写strcpy()函数?(10分)
已知strcpy函数原型是:
char *strcpy(char *strDest, const char *strSrc); |
其中:strDest是目的字符串,strSrc是源字符串;
不调用C++/C的字符串函数,请编写函数strcpy。
++++立钻哥哥:
char *myStrcpy(char *strDest, const char* strSrc){ if(strDest == NULL || strSrc == NULL){ return NULL; }
char *strDestCopy = strDest; while((*strDest++ = *strSrc++) != ‘\0’);
return strDestCopy; }
|
char *myStrcpy(char *strDest, const char* strSrc){ Assert((strDest != NULL) && (strSrc != NULL));
char *tmp = strDest; while((*strDest++ = *strSrc++) != ‘\0’);
return tmp; }
|
char *myStrcpy(char *dst, const char* src){ char *dcp; for(dcp = dst; *dcp = *src; dcp++, src++);
return dst; }
|
##A.1四、以下两种写法有什么区别?(5分) |
++A.1四、以下两种写法有什么区别?(5分)
一、 for(int i = 0; i < NUM; i++){ if(a < b){ DoSomething1(); }else{ DoSomething2(); } }
二、 if( a < b){ for(int i = 0; i < NUM; i++){ DoSomething1(); }
}else{ for(int i = 0; i < NUM; i++){ DoSomething2(); } }
|
++++立钻哥哥:
++++第一种写法:
--优势:程序简洁;
--缺点:多执行了N-1次逻辑判断,而且打断了循环“流水线”做用,使得编译器不能对循环进行优化处理,下降了效率;
++++第二种写法:
--优势:循环的效率高;
--缺点:程序不简洁;
##A.1五、关键字static在C语言中的做用?(5分) |
++A.1五、关键字static在C语言中的做用?(5分)
++++立钻哥哥:
++++一、在函数体内,一个被声明为静态的变量在这一函数调用过程当中维持不变;
++++二、在模块内(一个.c文件内),被声明的静态变量能够被模块内全部函数访问,但不能被模块外的其余函数访问;
++++三、在模块内,一个被声明为静态的函数只能被同一模块内的其余函数调用;
##A.1六、C++是安全类型的语言吗?(2分) |
#第二篇:Cocos2dx和C++知识点 |
#第二篇:Cocos2dx和C++知识点
++++B.一、对Cocos2dx的总体描述,总体认识?
++++B.二、如何阅读分析Cocos2dx源码及总体框架?
++++B.三、介绍一下你的项目?
++++B.四、使用Cocos2dx的心得?
++++B.五、是否了解CocoStudio?
++++B.六、用过哪些UI控件?
++++B.七、Cocos2dx的消息传递机制?
++++B.八、Cocos2dx内存自动回收机制?
++++B.九、Cocos2dx触摸机制?
++++B.十、在CCLayer处理用户触摸?
++++B.十一、Cocos2dx触摸分发器?
++++B.十二、Cocos2dx中图片的缓存和加载方式?
++++B.1三、常见的内存管理的方式?
++++B.1四、C++显式堆内存管理?
++++B.1五、C++11中的智能指针?
##B.一、对Cocos2dx的总体描述,总体认识? |
++B.一、对Cocos2dx的总体描述,总体认识?
++++立钻哥哥:
++++Cocos2dx的游戏元素是:大总管CCDirector,场景CCScene,层CCLayer,精灵CCSprite,再加上动做CCAction,再配合一些动画CCAnimation和粒子特效CCParticleSystem等就构成了Cocos2dx游戏;
++++游戏领域做为GUI的先驱,其计算机技术应用也引领着软件开发前沿,好比Cocos2d-3.0系列大量采用了C++11特性:override和final、lambda表达式等;
++++Cocos2dx游戏框架:内存管理、图层渲染;
++Cocos2dx是一个简单而强大的二维游戏引擎
++++立钻哥哥:Cocos2dx的原型是Cocos2d,目的是封装底层绘图代码,简化2D游戏的开发过程,避免每次都“从新发明轮子”;
++++从本质上说:Cocos2d是一个图形引擎,封装了复杂的图形接口,经过抽象出精灵、动做等概念,下降了游戏开发难度,简化了开发过程;
++++Cocos2dx:基于Cocos2d-iPhone的多平台二维游戏引擎,为开发者封装了功能强大的绘图代码,使开发者专一于游戏开发而不是绘图操做;
++++AppDelegate:Cocos2dx项目中的程序入口文件,提供对程序生命周期的控制事件;
++++CCNode::addChild方法:用于将一个游戏元素添加到另外一个元素中;
++简单介绍一下Cocos2d的特性:
++++流程控制(flow control):很是容易管理不一样场景(scene)之间的流程控制;
++++精灵(sprite):快速而方便的精灵用于显示一切可见的元素;
++++节点(node):基于树结构的分层组织方式,方便管理不一样层次的游戏元素,同时提供了统一管理的计时器(scheduler);
++++动做(action):应用于精灵或其余游戏元素的动画效果,能够组合成复杂的动做,如移动(move)、旋转(rotate)和缩放(scale)等;
++++特效(effect):包括波浪(wave)、旋转(twirl)和透镜(lens)等视觉特效;
++++平面地图(tiled map):支持矩形和六边形的平面地图;
++++菜单(menu):建立游戏中常见的菜单;
++++用户输入:提供接受用户触摸事件、传感器(如加速度计)等输入的简单解决方案;
++++文档(document):编程指南,API参考、视频教学以及不少简单可靠的测试样例;
++++MIT许可:免费开放的协议,可是请谨记尊重版权;
++++基于OpenGL:深度优化的绘制方式,支持硬件加速;
++导演(CCDirector)
++++立钻哥哥:在Cocos2dx引擎中,CCDirector类是整个游戏的组织和控制核心,游戏的运行规则,游戏内的CCScene(场景)、布景(CCLayer)、角色(CCSprite)等的运动,均由CCDirector管理,其在游戏中起着指定游戏规则让游戏内的场景、布景和任务有序的运行;
+++++在整个游戏里面,通常只有一个导演,游戏开始和结束时,都须要调用CCDirector的方法完成游戏初始化或销毁工做,其提供了一些场景管理的方法,如runWithScene,drawScene,pushScene和replaceScene等;
++++CCDirector控制FPS的显示隐藏,窗口大小,游戏的进入,退出,关卡的切换,取得正交模式,取得正在运行的场景,取得GL视图,游戏主循环入口等等;
##B.二、如何阅读分析Cocos2dx源码及总体框架? |
++B.二、如何阅读分析Cocos2dx源码及总体框架?
++++立钻哥哥:阅读源代码的最好方式是top-down的方式:先弄懂整个框架,再重点突破重要和感兴趣的模块;
++一、先看看测试用例TestCpp中的主函数,也是整个Win32程序的入口
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int mCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine);
//create the application instance AppDelegate app; CCEGLView* eglView = CCEGLView::sharedOpenGLView(); eglView->SetViewName(“TestCpp”); eglView->setFrameSize(1028, 720);
return CCApplication::sharedApplicaiton()->run(); } //立钻哥哥:int APIENTRY _tWinMain(){} |
++++这个入口有2个很是重要的类CCEGLView和CCApplication,在整个程序中都是单例;
+++++[CCEGLView]:是用来管理窗口和绘制;在CCEGLView::Create()中作了一下工做:
--A、registerClass注册窗口:其中很是重要的消息处理函数CCEGLView::_WindowProc()就是在这个地方定义的;整个游戏中的窗口的键盘、鼠标消息响应就能够在这个函数中进行处理;
--B、initGL初始化OpenGL引擎;(CCEGLView::initGL()中设置了像素的格式,建立了OpenGL的RenderContext,OpenGL最终渲染的结果会显示到该窗口的DC上)
++二、再看看CCApplication
++++立钻哥哥:CCApplication是用来管理程序的逻辑,最后一句CCApplication::sharedApplication()->run(); :整个程序就开始告诉运转起来了;
CCApplication* CCApplication::sharedApplication(){ CC_ASSERT(sm_pSharedApplication); return sm_pSharedApplicaition; } |
++AppDelegate是Application的子类,在这个子类的构造函数中声明了这个全局惟一的静态变量:sm_pSharedApplication;
CCApplication:CCApplication() : m_hInstance(NULL), m_hAccelTable(NULL){ m_hInstance = GetModuleHandle(NULL); m_nAnimationInterval.QuadPart = 0; CC_ASSERT(!sm_pSharedApplication); sm_pSharedApplication = this; } //立钻哥哥:CCApplication::CCApplication(){} |
+++Application::Run()作了什么,让整个程序运行起来了:
int CCApplication::run(){ PVRFrameEnableControlWindow(false);
//Main message Loop: MSG msg; LARGE_INTEGER nFreq; LARGE_INTEGER nLast; LARGE_INTEGER nNow;
QueryPerformanceFrequency(&nFreq); QueryPerformanceCounter(&nLast);
//Initialize instance and cocos2d if(!applicationDidFinishLaunching()){ return 0; }
CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView(); pMainWnd->centerWindow(); ShowWindow(pMainWnd->getHWnd(), SW_SHOW);
while(1){ if(!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ //Get current time tick QueryPerformanceCounter(&nNow);
//If it’s the time to draw next frame, draw it, else sleep a while. if(nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart){ nLast.QuadPart = nNow.QuadPart; CCDirector::sharedDirector()->mainLoop(); }else{ Sleep(0); } continue; } //立钻哥哥:if(!PeekMessage()){}
if(WM_QUIT == msg.message){ //Quit message loop break; }
//Deal with windows message
if(!m_hAcceelTable || !TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg)){ TranslateMessage(&msg); DispatchMessage(&msg); }
return (int)msg.wParam;
} //立钻哥哥:while(1){}
} //立钻哥哥:int CCApplication::run(){} |
++++[applicationDidFinishLaunching()]:这部分和测试用例有关系;
++++在while(1){}主循环中作了两件事:
--1A、转发窗口消息,交给以前定义的CCEGLView::_WindowProc()进行处理;
--2B、每隔m_nAnimationInterval.QuadPart时间,也就是游戏的一帧,进行一次处理;
++三、最重要的一个类CCDirector导演类
++++立钻哥哥:CCDirector导演类是一个单例,负责整个游戏场景管理,逻辑更新以及绘制;
++++CCDirector::sharedDirector()->mainLoop()的每帧的mainLoop()都作了啥事情:
void CCDisplayLinkDirector::mainLoop(void){ if(m_bPurgeDirectorInNextLoop){ m_bPurgeDirectorInNextLoop = false; purgeDirector(); }else if(!m_bInvalid){ drawScene();
//release the objects CCPoolManager::sharedPoolManager()->pop(); }
} //立钻哥哥:void CCDisplayLinkDirector::mainLoop(){} |
++++CCDirector导演类的每帧作的最重要的事情就是drawScene():
void CCDirector::drawScene(void){ ... ...
if(!m_bPaused){ m_pScheduler->update(m_fDeltaTime); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//draw the scene if(m_pRunningScene){ m_pRunningScene->visit(); }
//swap buffers if(m_pobOpenGLView){ m_pobOpenGLView->swapBuffers(); }
} //立钻哥哥:void CCDirector::drawScene(){} |
++++CCDirector::drawScene()作了两方面的工做:
--1A、更新调度器m_pScheduler:好比场景中的动做等;
--2B、绘制场景中的对象结点,树形的方式;
##B.三、介绍一下你的项目? |
++B.三、介绍一下你的项目?
++++立钻哥哥:我一共准备了N个项目,其中2个项目已发布在360平台上:
++++《ylzServPlane》:飞机大战,是基于Cocos2dx-2.2.3框架,利用这个小游戏,主要是熟悉Cocos2dx-2.2.3开发环境,掌握利用Cocos2dx框架开发游戏的基本技能;
++++《ylzServFind》:找宝石,是基于Cocos2dx-3.2框架,利用这个小游戏,主要是熟悉Cocos2dx-3.2开发环境,掌握3.0系列与2.0系列的差别和相关开发技能;
++++项目练习是我之后一个重要的学习途径:经过一个项目熟悉一个开发框架;
++++如今正在作的还有:《ylzServGuess》猜猜看,这个游戏很重要,肩负着三大任务:http、sqlite、UI等任务,这个项目基于Cocos2dx-2.2.2框架;
++++之后会陆续改写更多项目:《ylzServ塔防》、《ylzServ找你妹》、《ylzServ太空大战》、《ylzServ****》;
++++之后重点突破领域有:TileMap瓦片地图项目、CocosStudioUI场景动画项目等;
##B.四、使用Cocos2dx的心得? |
++B.四、使用Cocos2dx的心得?
++++立钻哥哥:Cocos2dx自己是C++的,尽管开发团队为了下降学习难度和入门门框作了不少工做,可是若是C++功底不够,我以为也学不到什么东西,充其量学会了使用一个工具而已;
++++做为一个优秀的程序员,数学是很是重要的;
++++C/C++仍是值得学习的,虽然这个比较难,可是自有其价值所在;
##B.五、是否了解CocoStudio? |
++B.五、是否了解CocoStudio?
++++立钻哥哥:CocoStudio做为触控推出的一款工具,确定是有其战略意义的;
++++CocoStudio做为专业的UI、场景、动画、数据等开发工具,其功能至关强大,是之后必须认真学习掌握的必备工具;
++++CocosStudio是一套专业的永久免费的游戏开发工具集,帮助开发快速建立游戏资源,将大部分繁琐的游戏开发工做使用编辑器来快速制做;
++++CocoStudio包含了游戏开发中核心的几个游戏编辑器:UI编辑器、动画编辑器、场景编辑器、数据编辑器,用于处理游戏中的动画资源、UI界面、游戏场景、游戏数据,针对于开发团队中不一样的职业进行深度设计,规范了整个开发流程,让开发团队中每一个人各执其职,发挥本身最大的做用;
++++[动画编辑器]:用于编辑游戏中使用的角色动画、特效动画、场景动画等动态的游戏资源;(主要使用人员是:美术设计师)
++++[UI编辑器]:用于编辑游戏中的全部的图形界面;(主要使用人员是美术设计师)
++++[数据编辑器]:用于将数值策划编辑的数值表导入数据编辑器中,将复杂表进行分解,导出成属性表,数值表等几种经常使用的数据文件;
++++[场景编辑器]:用于编辑游戏中的场景元素、游戏关卡;(主要使用人员是策划或者关卡设计师)
##B.六、用过哪些UI控件? |
++B.六、用过哪些UI控件?
++++立钻哥哥:UI控件其实不少的,留意了,用过一次,基本就会了,若是没有注意到,就不会;
++++常见UI控件:CCSprite、CCNode、CCLayer、CCScene;
++++[CCScale9Sprite]:九宫格Sprite;
++++[CCControlButton]:事件按钮;
++++[CCControlSlider]:拖动条;
++++[CCControlColorPicker]:颜色选择器;
++++[CCControlSwitch]:开关控件;
++++[CCControlPotentionmeter]:压力计;
++++[CCControlStepper]:分段控件;
++++[CCScrollView]:滚动视图;
++++[CCTableView]:列表视图;
##B.七、Cocos2dx的消息传递机制? |
++B.七、Cocos2dx的消息传递机制?
++++立钻哥哥:
++++[一、采用函数回调]:主要是用于MenuItem:
++++[二、TouchEvent响应]:为更多的响应处理提供可能;
++++[三、触摸监听绑定]:触摸函数能够用lambda来写;
##B.八、Cocos2dx内存自动回收机制? |
++B.八、Cocos2dx内存自动回收机制?
++++立钻哥哥:Cocos2dx提供了一种相似Java的内存回收机制;(在C++中,再也不使用的变量,须要手动释放(delete),否则内存就会溢出)
++++在使用Cocos2dx时,在新建立实例时,加入autorelease(),这样就能够自动释放再也不须要的内存了:
{ CCScene* pScene = CCScene::node(); CCLayer* pLayer = new MyTestController(); pLayer->autorelease(); } |
++++为了实现对象的引用计数记录,Cocos2dx实现了本身的根类CCObject,引擎中的全部派生类都派生自CCOject,CCObject的定义:
class CC_DLL CCObject : public CCCopying{ public: unsigned int m_uID; //对象id,在脚本引擎中使用 int m_nLuaID; //Lua中的引用ID,一样被脚本引擎使用
protected: unsigned int m_uReference; //引用数量 bool m_bManaged; //标识此对象是否已设置为autorelease
public: CCObject(void); virtual ~CCObject(void); void release(void); void retain(void); CCObject* autorelease(void); CCObject* copy(void); bool isSingleRefrence(void); unsigned int retainCount(void); virtual bool isEqual(const CCObject* pObject); virtual bool update(ccTime dt){ CC_UNUSED_PARAM(dt); }; friend class CCAutoreleasePool; }; //立钻哥哥:class CC_DLL CCObject:public CCCopying{} ++++每一个对象包含一个用来控制生命周期的引用计数器,它就是CCObject的成员变量m_uReference; ++++咱们能够经过retainCount()方法得到对象当前的引用计数值; ++++autorelease()的做用是将对象放入自动回收池(CCAutoreleasePool):当回收池自身被释放的时候,就会对池中的全部对象执行一次release()方法,实现灵活的垃圾回收; ++++经过回收池管理器CCPoolManager的push()或pop()方法来建立或释放回收池,其中CCPoolManager也是一个单例对象; ++++引擎维护着一个回收池,全部的autorelease对象都添加到了这个池中; |
++++自动回收池是可嵌套的:多个自动回收池排列成栈结构,当咱们手动建立了回收池后,回收池会压入栈的顶端,autorelease对象仅添加到顶端的池中;当顶层的回收池被弹出释放时,它内存全部的对象都会被释放一次,此后出现的autorelease对象则会添加到下一个池中:
//步骤a obj1->autorelease(); obj2->autorelease();
//步骤b CCPoolManager::sharedPoolManager()->push();
//步骤c for(int i = 0; i < n; i++){ obj_array[i]->autorelease(); }
//步骤d CCPoolManager::sharedPoolManager()->pop();
//步骤e obj3->autorelease();
++++当执行步骤a时,obj1和obj2被加入到回收池1中; ++++步骤b建立了一个新的回收池,此时回收池2接管全部autorelease操做; ++++步骤c是一个循环,其中把n个对象加入回收池2中; ++++步骤d释放了回收池2,所以回收池2中的n个对象都被释放了一次,同时回收池1接管autorelease操做; ++++步骤e调用obj3的autorelease()方法,把obj3加入回收池中; |
++Cocos2dx内存管理原则
++++1A、程序段必须成对执行retain()和release()或者执行autorelease()来开始和结束对象的引用;
++++2B、工厂方法返回前,应经过autorelease()结束该对象的引用;
++++3C、对象传值前,应考虑到新旧对象相同的特殊状况;
++++4D、尽可能使用release()而不是autorelease()来释放对象引用,以确保性能最优;
++++5E、保存CCObject的子类对象时,应严格使用Cocos2dx提供的容器,避免使用STL容器,对象必须以指针形式存入;
++++6F、若是但愿自定义的类也拥有Cocos2dx的内存管理功能,能够把CCObject做为自定义的基类,并在实现类时严格遵照Cocos2dx的内存管理原则;
++复杂的内存管理
++++内存管理一直是一个不易处理的问题,开发者必须考虑分配回收的方式和时机,针对堆和栈作不一样的优化处理等等;
++++内存管理的核心是动态分配的对象必须保证在使用完毕后有效地释放内存,即管理对象的生命周期;
++++过于零碎的对象分配回收可能致使堆中的内存碎片化,下降内存的使用效率;
++++Boost库引入的智能指针(smart pointer)从对象全部权传递的角度来解决内存管理问题;(各类基于C++的第三方工具库和引擎每每都会实现本身的智能内存管理机制来解决内存管理的难题,试图将开发者从烦琐而晦涩的内存管理中解放出来)
++现有的智能内存管理技术
++++立钻哥哥:实现智能管理内存的技术主要有两种:一是引用计数;二是垃圾回收;
++++[引用计数]:它是一种颇有效的机制,经过给每一个对象维护一个引用计数器,记录该对象当前被引用的次数;引用计数的重要规则是每个程序片断必须负责任地维护引用计数,在须要维持对象生存的程序段的开始和结束分别增长和减小一次引用计数,这样咱们就能够实现十分灵活的智能内存管理了;(引用计数解决了对象的生命周期管理问题,但堆碎片化和管理烦琐的问题仍然存在)
++++[垃圾回收]:它经过引入一种自动的内存回收器,试图将程序员从复杂的内存管理任务中彻底解放出来;垃圾回收器还能够压缩使用中的内存,以缩小堆所须要的工做空间;
++工厂方法
++++立钻哥哥:工厂方法是程序设计中一个典型的设计模式,指的是基类中只定义建立对象的接口,将实际的实现推迟到子类中;
++++工厂方法返回前,经过autorelease()结束该对象的引用
CCObject* factoryMethod(){ CCObject* ret = new CCObject();
... ... //这里对ret对象进行必要的初始化操做
ret->autorelease(); return ret; } |
++释放:release()仍是autorelease()
++++立钻哥哥:autorelease()并非毫无代价的,其背后的垃圾池机制一样须要占用内存和CPU资源,每次执行autorelease()的过程,实际上对应的是执行成对的retain()和release(),以及一次成对的容器存取,还包括其余的逻辑判断;
++++过多没必要要的autorelease()将致使垃圾池臃肿膨胀,在存在大量内存操做的过程当中会尤其严重地挤占原本就紧张的系统资源;
++++建议在开发过程当中应该避免滥用autorelease(),只在工厂方法等不得不用的状况下使用,尽可能以release()来释放对象引用;
++Cocos2dx中与内存管理有关的宏
++++[CC_SAFE_DELETE(p)]:使用delete操做符删除一个C++对象p,若是p为NULL,则不进行操做;
++++[CC_SAFE_DELETE_ARRAY(p)]:使用delete[]操做符删除一个C++数组p,若是p为NULL,则不进行操做;
++++[CC_SAFE_FREE(p)]:使用free()函数删除p,若是p为NULL,则不进行操做;
++++[CC_SAFE_RELEASE(p)]:使用release()方法释放Cocos2dx对象p的一次引用,若是p为NULL,则不进行操做;
++++[CC_SAFE_RELEASE_NULL(p)]:使用release()方法释放Cocos2dx对象p的一次引用,再把p赋值为NULL,若是p已经为NULL,则不进行操做;
++++[CC_SAFE_RETAIN(p)]:使用retain()方法增长Cocos2dx对象p的一次引用;若是p为NULL,则不进行操做;
##B.九、Cocos2dx触摸机制? |
++B.九、Cocos2dx触摸机制?
++++立钻哥哥:返回true,则本层接受;若是是false,就不接受,向下传递;
//2.0版本 virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); ++++[ccTouchesBegan]:触摸事件开始,也就是手指按下时; ++++[ccTouchesMoved]:触摸移动事件,也就是手指在屏幕滑动的过程; ++++[ccTouchesEnded]:触摸事件结束,也就是手指松开时; ++++[ccTouchesCancelled]:打断触摸事件,通常是系统层次的消息,如手机来电话,触摸事件就会被中断;
|
//3.0版本 //单点触摸 virtual bool onTouchBegan(Touch *touch, Event *unused_event); virtual void onTouchMoved(Touch *touch, Event *unused_event); Virtual void onTouchEnded(Touch *touch, Event *unused_event); virtual void onTouchCancelled(Touch *touch, Event *unused_event);
//多点触摸 virtual void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event); virtual void onTouchesMoved(const std::vector<Touch*>& touches, Event *unused_event); virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event *unused_event); virtual void onTouchesCancelled(const std::vector<Touch *>& touches, Event* unused_event); |
++++【单点触摸】:只有注册的Layer才能接收触摸事件:
--A、[onTouchBegan()]:
----A.一、若是返回true:本层的后续Touch事件能够被触发,并阻挡向后层传递;
----A.二、若是返回false:本层的后续Touch事件不能被触发,并向后传递,也就是不会调用;
--B、[onTouchMoved()]:
virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent); |
----B.一、返回false,则ccTouchMoved(), ccTouchEnded()不会再接收到消息;
----B.二、返回true,则ccTouchMoved(), ccTouchEnded()能够接受到消息;
++小结
++++[CCLayer触摸支持]:CCLayer提供了一套现成的触摸实现,只需启用TouchEnable属性便可接收Cocos2dx的标准触摸事件;(开发者须要重载以ccTouches为前缀的响应函数)
++++[标准触摸事件]:Cocos2dx提供的一种触摸事件,注册了这种事件的全部对象都会平等地接收到触摸事件,而且对于多点触摸,标准触摸事件会同时提供全部的触摸点;
++++[带目标的触摸事件]:这是另外一种触摸事件,注册了这种事件的对象会按照优先级投递,先接收到事件的对象有权吞噬此事件,以阻止把事件分发给其余对象;(利用吞噬功能屏蔽某个事件)(例如:一个提示框能够屏蔽掉提示框之外的全部对象接收到触摸事件)
++++[触摸分发器(CCTouchDispatcher)]:由引擎调度、负责接收来自系统的触摸事件;(这容许任何对象在分发器中注册触摸事件,并根据Cocos2dx的机制把触摸事件分发给注册者)(开发者能够利用addStandardDelegate与addTargetedDelegate方法把本身注册为事件接收者,利用removeDelegate方法取消曾经注册过的触摸事件)
##B.十、在CCLayer处理用户触摸? |
++B.十、在CCLayer处理用户触摸?
++++立钻哥哥:CCLayer继承自CCNode,在CCLayer中能够实现单点触摸、多点触摸和重力感应回调等3种不一样形式的交互;
++++这里咱们来重点讨论一下:在CCLayer处理用户触摸;
++在用户自定义的图层处理用户触摸事件步骤
++++A、步骤1:编写图层类继承CCLayer;
++++B、步骤2:在初始化阶段(init方法),将此层的属性设置为接收触摸消息:
setTouchEnabled(true); //开启屏幕触摸 |
++++C、步骤3:重载CCLayer函数:virtual void registerWithTouchDispatcher(void);,由于默认的方式为:[Standard Touch Delegate],须要在函数中添加如下语句:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); |
--第二个参数是代理的优先级,若是数值越小优先级越高;
--第三个参数是true:表示当前图层处理消息后再也不进行消息的后续传递,若是须要继续传递消息须要设置为false;
++++D、步骤4:重载触摸响应函数,接收触摸消息须要重载如下函数:
ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); //按下 ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); //滑动 ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); //抬起 |
++++E、步骤5:在触摸响应函数中经过pTouch获得用户的触摸点:
CCPoint point = pTouch->getLocation(); |
##B.十一、Cocos2dx触摸分发器? |
++B.十一、Cocos2dx触摸分发器?
++++立钻哥哥:为了实现触摸事件,CCLayer已经封装好了简单的接口(继承了CCTouchDelegate类)来实现触摸事件的响应;
++++触摸事件有两种:标准触摸代理和目标触摸代理;
++++[标准触摸]:在层初始化时调用setTouchEnable(true); 方法,便可实现标准触摸,实现处理事件回调函数,处理触摸事件便可;
//optional virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);
|
void TouchLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){ if(pTouches->Count() == 1){ CCTouch *touch = dynamic_cast(pTouches->anyObject());
//因为在不一样平台下触摸点的坐标系与OpenGL呈现区域的参数可能不尽相同 CCPoint position = touch->locationInView(); //获取游戏画面中的点位置 positon = CCDirector::sharedDirector()->convertToGL(position);
//此到处理触摸事件
}else{ //若是不止一个触摸点,则在此处理多点触摸事件 }
} //立钻哥哥:void TouchLayer::ccTouchesMoved(){} |
void CCLayer::setTouchEnabled(bool enabled){ if(m_bTouchEnabled != enabled){ m_bTouchEnabled = enabled; if(m_bRunning){ if(enabled){ this->registerWithTouchDispatcher(); }else{ CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } } } } //立钻哥哥:void CCLayer::setTouchEnabled(){} |
++++进入[registerWithTouchDispatcher()]方法中看到调用了:pDispatcher->addStandardDelegate(this, 0); 方法,也就是将该对象注册为标准代理; ++++对于标准代理,只要事件分发器接收到用户的触摸事件,就会分发给全部的订阅者; ++++当系统存在多个触摸点时,全部的触摸点都会传递给回调函数,而后许多状况下每一个触摸点之间是独立的,屏幕上是否存在其余触摸点咱们并不关心; |
++++[目标代理]:要我该层使用目标代理,首先调用addTargetedDelegate()开启目标代理;
++一、首先调用addTargetedDelegate()开启目标代理: CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true); ++++第二个参数为优先级;第三个参数为是否吞噬触摸;
|
++二、而后重载事件回调函数: virtual bool ccTouchesBegan(CCTouch *pTouches, CCEvent *pEvent); virtual void ccTouchesMoved(CCTouch *pTouches, CCEvent *pEvent); virtual void ccTouchesEnded(CCTouch *pTouches, CCEvent *pEvent); virtual void ccTouchesCancelled(CCTouch *pTouches, CCEvent *pEvent); ++++第一个参数为CCTouch*,已再也不是CCSet*集合,而是一个触摸点; ++++ [ccTouchBegan()]方法返回的是一个布尔值,表示声明是否要捕捉传入的这个触摸点,返回true表示要捕捉,那么在后面Moved和Ended中处理触摸事件便可; ++++若是注册的时候选择了要吞噬触摸,触摸事件不会再分发下去,则优先级低的对象没法接收到触摸;
|
++三、实现一个对象的触摸代理分如下几步: ++++A、第1步:此对象继承CCStandardTouchDelegate/CCTargetedTouchDelegate接口; ++++B、第2步:使用addStandardDelegate/addTargetedDelegate方法把本身注册给触摸事件分发器CCTouchDispatcher; ++++C、第3步:重载事件处理回调函数;(注意目标代理触摸开始事件Began中必须针对须要接受的事件返回true) ++++D、第4步:当再也不须要接收触摸事件,使用removeDelegate方法来注销触摸事件的接收;
|
++触摸分发器原理
//来看看CCDispatcher的主要成员
//注册标准触摸事件 void addStandardDelegete(CCTouchDelegate *pDelegate, int nPriority);
//注册目标触摸事件 void addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches);
//注销触摸派发 void removeDelegate(CCTouchDelegate *pDelegate); void removeAllDelegate(void);
//从新设定指定对象的事件优先级 void setPriority(int nPriority, CCTouchDelegate *pDelegate);
//分发事件 void touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex);
protected: CCArray* m_pTargetedHandlers; //记录注册了带目标的触摸事件对象 CCArray* m_pStandardHandlers; //记录注册了标准触摸事件的对象 |
##B.十二、Cocos2dx中图片的缓存和加载方式? |
++B.十二、Cocos2dx中图片的缓存和加载方式?
++++立钻哥哥:在Cocos2dx中进行图片加载时,若是是第一次加载图片就要把图片加载到缓存,而后从缓存中加载图片,若是缓存中已经有了,就直接从缓存中加载;
++++图片的缓存有两种类型:一种是CCTextureCache,另外一种是CCSpriteFrameCache;
++++[CCTextureCache]:是普通的图片加载缓存,通常直接加载的图片都会放到这个缓存里面,这是一个会常常用到的缓存,这个缓存若是不手动释放,它是会一直占用内存的,它有不少函数接口,都是为了方便进行内存管理等的;
--[removeAllTextures()]:清空全部的缓存;
--[removeUnusedTextures()]:清除没用的缓存;
--[dumpCachedTextureInfo()]:输出缓存的信息;
##B.1三、常见的内存管理的方式? |
++B.1三、常见的内存管理的方式?
++++立钻哥哥:
++++1A、在适当的时候释放内存;
++++2B、使用纹理贴图集的方法,尽可能拼接图片,使得图片的边长保持在2的N次方,同时最好将有一点逻辑关系的图片打包在一张大图里,从而可以有效地节约内存;
++++3C、使用CCSpriteBatchNode来减小相同图片的渲染操做;
##B.1四、C++显式堆内存管理? |
++B.1四、C++显式堆内存管理?
++++立钻哥哥:C++使用new关键字在运行时给一个对象动态分配内存,并返回堆上内存的地址供应用程序访问,经过动态分配的内存须要在对象再也不被使用时经过delete运算符将其内存归还给内存池;
++++显式的内存管理在性能上有必定优点,可是极其容易出错,事实上,咱们老是不能经过人的思惟去保证一个逻辑的正确;
++++不能正确处理堆内存的分配与释放一般会致使如下问题:
--1A、野指针:指针指向的内存单元已经被释放,可是其余一些指针可能还指向它,这些内存可能已经被从新分配给其余对象,从而致使不可预测的结果;
--2B、重复释放:重复释放一个已经被释放的内存单元,或者释放一个野指针(也是重复释放)都会致使C++运行时错误;
--3C、内存泄露:再也不被使用的内存单元若是不被释放就会一直占用内存单元,若是这些操做不断重复就会致使内存占用不断增长,在游戏中内存泄露尤为严重,由于可能每一帧都在建立一个永远不会被回收的游戏对象;
##B.1五、C++11中的智能指针? |
++立钻哥哥推荐的拓展学习连接(Link_Url):
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++Unity5.x用户手册:http://www.javashuo.com/article/p-ufnzpmga-s.html
++++Unity面试题ABC:http://www.javashuo.com/article/p-mwacxwca-gm.html
++++Unity面试题D:http://www.javashuo.com/article/p-wuwcrclr-s.html
++++Unity面试题E:http://www.javashuo.com/article/p-hmabbtmc-ba.html
++++Unity面试题F:http://www.javashuo.com/article/p-olslkfao-cq.html
++++Cocos2dx面试题:http://www.javashuo.com/article/p-daozmsii-cz.html
++++Unity知识点0001:http://www.javashuo.com/article/p-ryvdxxjr-ep.html
++++Unity知识点0008:http://www.javashuo.com/article/p-kxgstxls-gu.html
++++Unity引擎基础:http://www.javashuo.com/article/p-beommoeb-ka.html
++++Unity面向组件开发:http://www.javashuo.com/article/p-eigmuvut-dt.html
++++Unity物理系统:http://www.javashuo.com/article/p-nqvvciwv-kd.html
++++Unity2D平台开发:http://www.javashuo.com/article/p-ycaagdtj-hs.html
++++UGUI基础:http://www.javashuo.com/article/p-rukxwckw-mc.html
++++UGUI进阶:http://www.javashuo.com/article/p-wcatruhq-gt.html
++++UGUI综合:http://www.javashuo.com/article/p-dkccmqii-gg.html
++++Unity动画系统基础:http://www.javashuo.com/article/p-mbrdouxy-dq.html
++++Unity动画系统进阶:http://www.javashuo.com/article/p-aqaqpbkh-bp.html
++++Navigation导航系统:http://www.javashuo.com/article/p-dswwllas-t.html
++++Unity特效渲染:http://www.javashuo.com/article/p-ckojjyfj-bp.html
++++Unity数据存储:http://www.javashuo.com/article/p-bvlzynso-m.html
++++Unity中Sqlite数据库:http://www.javashuo.com/article/p-ejutsbxl-ca.html
++++WWW类和协程:http://www.javashuo.com/article/p-dbwmhsav-cy.html
++++Unity网络:http://www.javashuo.com/article/p-sqrlntgh-dw.html
++++C#事件:http://www.javashuo.com/article/p-zmwruvql-gm.html
++++C#委托:http://www.javashuo.com/article/p-uozpymaf-gh.html
++++C#集合:http://www.javashuo.com/article/p-sfqfdqsf-ex.html
++++C#泛型:http://www.javashuo.com/article/p-xrttqngo-ee.html
++++C#接口:http://www.javashuo.com/article/p-vhlfplgv-dm.html
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:http://www.javashuo.com/article/p-olslkfao-cq.html
++++C#数据类型:http://www.javashuo.com/article/p-hmabbtmc-ba.html
++++Unity3D默认的快捷键:http://www.javashuo.com/article/p-wuwcrclr-s.html
++++游戏相关缩写:http://www.javashuo.com/article/p-mwacxwca-gm.html
++++设计模式简单整理:http://www.javashuo.com/article/p-rngqugib-hg.html
++++专题:设计模式(精华篇):http://www.javashuo.com/article/p-nbohnaya-hw.html
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++UML类图:http://www.javashuo.com/article/p-sxberuew-bm.html
++++U3D_Shader编程(第一篇:快速入门篇):http://www.javashuo.com/article/p-kyppgrac-gz.html
++++U3D_Shader编程(第二篇:基础夯实篇):http://www.javashuo.com/article/p-qkyowtli-hv.html
++++框架知识点:http://www.javashuo.com/article/p-eufbowgf-u.html
++++游戏框架(UI框架夯实篇):http://www.javashuo.com/article/p-cvemoigb-cu.html
++++游戏框架(初探篇):http://www.javashuo.com/article/p-zfpoilbc-hy.html
++++Lua快速入门篇(基础概述):http://www.javashuo.com/article/p-shernvtt-u.html
++++Lua快速入门篇(XLua教程):http://www.javashuo.com/article/p-pduvmusb-ho.html
++++Lua快速入门篇(Xlua拓展):http://www.javashuo.com/article/p-rrszijom-cm.html
++++UnityAPI.Rigidbody刚体:http://www.javashuo.com/article/p-phaztrtw-w.html
++++UnityAPI.Material材质:http://www.javashuo.com/article/p-ntyoqcng-q.html
++++UnityAPI.Android安卓:http://www.javashuo.com/article/p-fyyfgkck-q.html
++++UnityAPI.AndroidJNI安卓JNI:http://www.javashuo.com/article/p-kvxjsnzf-w.html
++++UnityAPI.Transform变换:http://www.javashuo.com/article/p-bfgrrhxl-cq.html
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--