从Cocos2d::Layer派生的类有一个指针数据成员.这个元素也有一个向量容器.调用vector::push_bac

A class derived from Cocos2d::Layer has a Pointer Data Member. This member also has vector container. When vector::push_back is called it crashes

本文关键字:有一个 向量 vector bac push 元素 调用 派生 Layer Cocos2d 数据成员      更新时间:2023-10-16

我尽了最大的努力编辑了这篇文章。希望它现在是最小的,完整的,可验证的示例

  • 我使用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 vector时,我都会得到EXP_BAD_ACCESS。

  • 如果我在虚拟init()方法之外初始化指针数据成员(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_pBar不存在于cocos2d::Scene中。在这种情况下,强制转换也不会有任何好处。

同样,这个强制转换(((GameWorldLayer*)scene))是不好的。您至少应该使用dynamic_cast

相关文章: