c++ - 从 Cocos2d::Layer 派生的类有一个指针数据成员。该成员也有 vector 容器。当调用 vector::push_back 时它会崩溃

标签 c++ vector cocos2d-x stdvector push-back

我尽最大努力编辑了这个。希望它现在是最小的、完整的和可验证的示例

-

  • 我正在为我们当前的游戏使用 Cocos2dx V3.6
  • 我描述的问题只发生在 cocos2d::Layer 的自定义派生类中
  • cocos2dx 使用静态创建函数来模拟 ObjC 版本的自动释放功能。在此创建函数中调用虚拟 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)你应该得到与我不断得到的相同的 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
 };

游戏世界图层.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();
}

酒吧.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__) */

酒吧.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

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

相关文章:

c++ - 如何使用 SHFILEOPSTRUCT 移动多个文件?

C++ 文件访问/输入和输出

android - 如何从 Android NDK 或 Cocos2dx 发送短信

c++ - 删除对象并在同一内存位置再次创建

c++ - 如何在 C++ 中实现超过 2000 个节点的最小生成树?

matlab - 在 3d 中绘制法向量

c++ - 访问存储在 vector 中的指针内的字符串时崩溃

运算符 '<' 的 C++ 重载并非每次都被使用

android - Cocos2dx 安卓 : Get data from file(assets/*) failed

cocos2d-x - 检测交叉点而不导致物体碰撞