开发者

is this a passable software design?

开发者 https://www.devze.com 2023-02-08 16:58 出处:网络
I\'m currently working on a game in c++. since there\'s no garbage collector one has always to carefully delete the objects and also make sure that such objects are not accessed anymore once they got

I'm currently working on a game in c++. since there's no garbage collector one has always to carefully delete the objects and also make sure that such objects are not accessed anymore once they got deleted.

Now as a project grows some objects may get referenced from more and more places. For example my units in the game may get referenced from the renderer, from the scene hierarchy, from the selection mechanism, from the HUD and so on. now - if a object gets deleted one has to make sure that all other classes that reference this object will be notified about it.

Or let's say it the other way arround - if i create a new class that may reference one of my units, i'll also have to change the code of the unit (or of the unit manager or whatever module delets the unit if it gets destroyed) to make sure this new module knows when the particular unit it currently references gets deleted.

Now I thoght there could be a simple event driven general purpose aproach to solve this problem by creating a baseclass to which one another object can subscribe. Something like this:

class DeletableBase;//forward declaration

class ISubscriber{
public:
    virtual someObjectGotDeleted(DeletableBase* deletedObject)=0;
};

class DeletableBase{
private:
    vector<ISubscriber*> subscribers;
pu开发者_运维知识库blic:
    virtual ~DeletableBase(){
        for(int i=0; i<subscribers.size(); i++)
            subscribers[i]->someObjectGotDeleted(this);
    }
    subscribeForDeleteEvent(ISubscriber* subscriber){
        subscribers.push_back(subscriber);
    }
};

with that - if i reference any object that inherits from this class from a new class i can simply add myself as a subscriber and if the object will be deleted from any other place I will get notifed about it.

is this a "clean" way of coding?


If this is purely about memory management (rather than state change), use a smart pointer instead. Start with shared_ptr, then optimize using make_shared/allocate_shared or boost::intrusive_ptr if it's too slow.


One thing you'll have to consider (especially if you're writing a game) is that when one of your subscribed objects gets deleted on the main thread, your game will most likely block until each of its subscribers is done doing whatever it's going to do upon deletion of the object. That may affect game performance if you're not careful.


You have to avoid dropping objects referenced by other objects, but not the other way around. Boost smart pointers will do 90% of the work for you.

P.S.: There is a garbage collector for C++ :-)


IMHO, you need to implement your own memory allocator. Instead of observing each instance, you may observe released memory for regarding instance type or class. Of course, in order to that, your memory allocator should be observable. You may use map or set like data structure or multi versions of them to notify observers more effectively. Which means, your memory manager will be a mediator and also observable.

In addition, if these releasing or notifying actions are independent of each other, you may use Command Pattern to separate execution and thread context. Hope this helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号