內容很多摘自
Aman JIANG(江超宇)翻譯的Box2D v2.0.1 使用者手冊
第11章 雜項(Loose Ends)
11.1 隱式摧毀
Box2D沒有使用引用計數。你摧毀了body後,它就確實不存在了。訪問指向已摧毀body的指標,會導致未定義的行為。 也就是說,你的程式可能會崩潰。以debug方式編譯出的程式,Box2D的記憶體管理器會將已被摧毀實體佔用的記憶體,都填上FDFDFDFD。一些時候, 這樣可以使你更容易的找到問題的所在,進而修複問題。
如果你摧毀了Box2D實體, 你要確保所有指向這實體的引用都被移除。如果只有實體的單個引用,處理起來就很簡單了。但如果有多個引用,你需要考慮是否去實現一個控制代碼類(handle class),將原始指標封裝起來。
當你使用Box2D時,會很經常建立並摧毀很多的物體(bodies), 形狀(shapes),關節(joints)。某種程度上,這些實體是由Box2D自動管理的。當你摧毀了一個body,所有跟它有關聯的形狀,關節,接觸都會自動被摧毀。這稱為隱式摧毀。任何與這些關節或接觸有串連的body也會被喚醒。這樣處理通常也比較方便的。但是,你應該要注意一個關鍵問題:
注意
當body被摧毀時,所有依附其上的形狀,關節也會被自動摧毀。你應該將任何指向這些形狀和關節的指標清零。否則之後你試圖訪問或者再次摧毀這些形狀或關節,你的程式會死得很慘。
大多數情況下,隱式摧毀還是很方便的,但也很容易使你的程式崩潰。你可能會將指向shape或關節的指標儲存起來,當有關聯的body摧毀時,這些指標就變得無效了。關節由某小段代碼建立,有時你會認為這關節跟其它body都沒有關係,但這隻會使事情變得更糟糕。比如,testbed就建立了一個b2MouseJoint用來操作螢幕上的body。
Box2D提供了一種回調機制,當隱式摧毀發生時,你的程式可以收到通知,從而將無效指標清零。
你可以實現一個b2DestructionListener,這樣當一個形狀或關節隱式摧毀時,b2World 就能通知你。
class MyDestructionListener : publicb2DestructionListener
{
void SayGoodbye(b2Joint* joint)
{
// remove all references tojoint.
}
};
你可以將摧毀監聽器(destruction listener)註冊到world對象中。在world對象初始化時,你就應該這樣做了。
myWorld->SetListener(myDestructionListener);