2016-06-11 64 views
1

我開始使用cocos2d-x,並遇到問題。下面的代碼在s->getChildrenCount();處拋出讀取訪問衝突錯誤。Sprite :: create()後懸掛Sprite指針成員變量

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成爲懸擺指針,它有事情做參考計數。我讀了如何引用計數的作品,但我沒有完全理解它。

sprite在init的末尾如何被破壞?誰在做?

解決此問題的正確方法是什麼?在Sprite::create()之後執行s->retain()並添加析構函數與s->release()?如果我這樣做,我看不到使用傳統C++ newdelete的好處。

回答

0

首先,沒有懸掛指針,但創建的指針不再存在,s現在是nullptr。這就是當您嘗試訪問getChildrenCount()方法時出現訪問衝突錯誤的原因。

使用create()方法創建的對象將在其創建方法結束後立即發佈。這意味着如果對象沒有引用並且未標記爲保留,則創建的對象將被解構。如果你想要改變這種行爲,你必須分別調用retain和release,就像你已經完成的那樣。

之一的s->retain()s->release()或引用計數一般的好處,與使用newdelete是,你不必擔心你的類,即外部的數據成員。 當你打電話給刪除時,你確定該資源不再在任何地方使用?通過使用引用計數和保留/釋放機制,這個問題變得不必要了。

+0

你是對的,我犯了一個錯誤 - 這是一個空指針,而不是一個懸掛指針。 「使用create()方法創建的對象只要創建方法結束,就會被評估爲被釋放。」 - 這在C++中如何實現? – takfuruya

+0

這是一個很好的問題,但不容易在評論中回答。嘗試搜索C++引用計數和智能指針。 –