单例:即只有一个类对象,且提供全局的访问权限
特点:
1.构造函数私有
2.私有的静态成员指针,标识是否已产生了单例实例
3.提供一个getInstance()方法来获取单例对象
下面已打飞机中的子弹管理类来说明,单例的用法及实现:
#ifndef _MANAGER_H_ #define _MANAGER_H_ #include "cocos2d.h"; //包含敌机和子弹的头文件 #include "BulletBullet.h"; #include "EnemyEnemyBase.h"; USING_NS_CC; //子弹和敌机管理器,做成单例 class Manager { public: static Manager * getInstance(); static void Manager::freeInstance(void); private: static Manager * m_manager; Manager(); bool init(); public: //使用以下的方法定义了俩个容器,并且实现了get方法,一定要注意get的返回值,这个返回的是引用 //官方建议容器最好不要在堆上分配内存空间,当我们在栈上分配内存空间的时候一定要传递引用,否则就出错了 Vector<EnemyBase *> & getEnemyVector(){return m_enemyVector;}; Vector<Bullet *> & getBulletVector(){return m_bulletVector;}; private: Vector<EnemyBase *> m_enemyVector; Vector<Bullet *> m_bulletVector; }; #endif
子弹管理类的.cpp文件
#include "Manager.h" Manager * Manager::m_manager = NULL; //在构造函数的初始化列表中初始化数组 Manager::Manager() : m_enemyVector(),m_bulletVector() { } Manager * Manager::getInstance() { if(m_manager == NULL) { m_manager = new Manager(); } return m_manager; } void Manager::freeInstance(void) { if(m_manager != NULL) { delete m_manager; m_manager = NULL; } }
3.在主场景中如何使用单例来管理子弹:
//场景切换完毕调用 void MainGame::onEnterTransitionDidFinish() { //必须先调用父类的函数 Layer::onEnterTransitionDidFinish(); //添加敌机,每秒添加一个 this->schedule(SEL_SCHEDULE(MainGame::addEnemy),1.0f); //添加子弹,每0.08秒产生一颗子弹 this->schedule(SEL_SCHEDULE(MainGame::addBullet),0.08f); //碰撞检测 this->schedule(SEL_SCHEDULE(MainGame::isHitEnemy),0.016f); } //碰撞检测 void MainGame::isHitEnemy(float tm) { } //添加子弹 void MainGame::addBullet(float tm) { auto bullet = Bullet::create(); bullet->initBullet("bullet1.png"); auto point = Point(m_player->getPositionX(), m_player->getPositionY()+m_player->getContentSize().height/2+10); bullet->setPosition(point); this->addChild(bullet); //将子弹添加到管理器中 auto & vector = Manager::getInstance()->getBulletVector(); vector.pushBack(bullet); log("%d",vector.size()); }