2016-06-11 3 views
1

Я начинаю с cocos2d-x, и у меня возникает проблема. Ниже кода выдается ошибка нарушения доступа к чтению в s->getChildrenCount();.Dangling Sprite указатель элемента переменной после Sprite :: create()

HelloWorldScene.h

class HelloWorld : public cocos2d::Layer 
{ 
public: 
    static cocos2d::Scene* createScene(); 
    virtual bool init(); 
    void update(float) override; 
    CREATE_FUNC(HelloWorld); 

private: 
    cocos2d::Sprite* s; 
}; 

HelloWorldScene.cpp

Scene* HelloWorld::createScene() 
{ 
    auto scene = Scene::create(); 
    auto layer = HelloWorld::create(); 
    scene->addChild(layer); 
    return scene; 
} 
bool HelloWorld::init() 
{ 
    if (!Layer::init()) 
    { 
     return false; 
    } 

    s = Sprite::create(); 
    this->scheduleUpdate(); 
    return true; 
} 
void HelloWorld::update(float delta) 
{ 
    int k = s->getChildrenCount(); 
    ... 
} 

Я думаю, что s становится оборванным указателем и что-то делать с подсчетом ссылок. Я читаю, как работает подсчет ссылок, но я не совсем понял это.

Как можно справиться с уничтожением спрайта в конце init? Кто это делает?

Каков правильный способ решения этой проблемы? Сделайте s->retain() после Sprite::create() и добавьте HelloWorldScene деструктор с s->release()? Если я это сделаю, я не вижу преимущества над использованием традиционных C++ new и delete.

ответ

0

Во-первых, нет обвисшего указателя, но созданный указатель больше не существует, а s - это nullptr. Вот почему вы получаете ошибку нарушения прав доступа при попытке получить доступ к методу getChildrenCount().

Объекты, созданные с использованием методов create(), будут оцениваться как выпущенные, как только они будут созданы в конце. Это означает, что если объект не имеет ссылок и не помечен для сохранения, созданный объект будет деконструирован. Если вы хотите, чтобы это поведение изменилось, вы должны вызвать сохранение и выпустить соответственно, как вы уже сделали.

Одним из преимуществ s->retain() и s->release() или подсчета ссылок в целом, по сравнению с использованием new и delete является то, что вам не придется беспокоиться о членстве данных за пределами вашего класса, т.е.. , когда вы вызываете delete, вы уверены, что ресурс больше не используется? Этот вопрос становится ненужным, используя подсчет ссылок и механизм сохранения/освобождения.

+0

Вы правы, я допустил ошибку - это нулевой указатель, а не свисающий указатель. «Объекты, созданные с использованием методов create(), будут оцениваться как выпущенные, как только они будут созданы в конце». - Как это возможно на C++? – takfuruya

+0

Это хороший вопрос, но нелегко ответить в комментарии. Попробуйте найти счетчик ссылок C++ и интеллектуальные указатели. –