我尽力编辑了此内容。希望它现在是最小,完整和可验证的示例

--


我在当前游戏中使用的是Cocos2dx V3.6
我描述的问题仅发生在cocos2d :: Layer的自定义派生类中
cocos2dx使用静态创建功能,该功能用于模仿ObjC版本的自动发布功能。在此create函数中将调用虚拟init()方法和构造函数。它是通过使用CREATE_FUNC宏生成的。
问题是如标题中所述。我有一个来自cocos2d :: Layer(GameWorldLayer)的自定义派生类。它具有一个指针数据成员(m_bar)。 m_bar还具有std:vector属性(m_container)。我在GameWorldLayer的重写的虚拟init()中初始化m_bar。因此,每当我尝试将某些内容推入m_container向量时,都会得到EXP_BAD_ACCESS。
如果我在虚拟init()方法之外初始化Pointer Data Member(m_bar),则一切正常。
简单来说,我只是不理解为什么在虚拟init()方法之外初始化指针数据成员会起作用,但是在内部初始化时却完全失败。


我试图简化代码,并使其保持最低限度(如果您在自己的IDE中尝试使用(我正在使用xcode btw)),则应该获得与我保持相同的EXP_BAD_ACCESS。 (我确定您已经知道,但您还需要cocos2dx 3.6)

GameWorldLayer.h

#ifndef __Flide__GameWorldLayer__
#define __Flide__GameWorldLayer__

#include "cocos2d.h"
#include "bar.h"
class GameWorldLayer : public cocos2d::Layer
{
private:
   Bar * m_bar;
public:

   static cocos2d::Scene* createScene();
   virtual bool init();

   CREATE_FUNC(GameWorldLayer);
   void AddSomethingToBar();
   ~GameWorldLayer();//destructor
 };


GameWorldLayer.cpp

#include "GameWorldLayer.h"

GameWorldLayer::~GameWorldLayer()
{
    delete m_bar;
}

cocos2d::Scene* GameWorldLayer::createScene()
{
   // 'scene' is an autorelease object
   auto scene = cocos2d::Scene::create();

   // 'layer' is an autorelease object
   auto layer = GameWorldLayer::create();

   // add layer as a child to scene
   scene->addChild(layer);

   // return the scene
   return scene;
}

bool GameWorldLayer::init()
{
   //1. super init first
   if ( !Layer::init())
   {
       return false;
   }

   m_bar = new Bar();

   return true;
}

void GameWorldLayer::AddSomethingToBar()
{
   m_bar->PushContainer();
}


Bar.h

#ifndef __Flide__bar__
#define __Flide__bar__
#include <vector>
#include <stdio.h>
using namespace cocos2d;
class Bar
{
private:

   std::vector<int>  m_container;
public:
   Bar(); //constructor
   ~Bar();//destructor

   void PushContainer(); //pushes something into m_container.
};
#endif /* defined(__Flide__bar__) */


Bar.cpp

#include "bar.h"
Bar::Bar()
{
}

Bar::~Bar()
{
   m_container.clear();
}

void Bar::PushContainer()
{
    m_container.push_back(1);//pushing an integer
}


我认为这不是必需的,只是为了完整性。我初始化GameWorldLayer,然后在AppDelegate :: applicationDidFinishLaunching()中调用GameWorldLayer :: AddSomethingToBar()。

bool AppDelegate::applicationDidFinishLaunching()
{
  ...
   // create a scene. it's an autorelease object
   auto scene = GameWorldLayer::createScene();
   ((GameWorldLayer*)scene)->AddSomethingToBar();
  ...
}

最佳答案

我的钱花在GameWorldLayer::init()上,而您却没有以您认为的方式来称呼它。 m_pBar将属于您在此处创建的图层:auto layer = GameWorldLayer::create();,并且将不属于您返回的Scene对象。

因此,您的Scene对象将无法访问m_pBar,因为m_pBarcocos2d::Scene中不存在。在这种情况下,投射也不会有任何好处。

另外,此强制转换(((GameWorldLayer*)scene))是错误的。您至少应使用dynamic_cast

关于c++ - 从Cocos2d::Layer派生的类具有指针数据成员。该成员还具有 vector 容器。调用vector::push_back时,它崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33008024/

10-11 01:30