对象应该在 C++ 中删除自己吗? [英] Should objects delete themselves in C++?

查看:22
本文介绍了对象应该在 C++ 中删除自己吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去 4 年我一直在使用 C#,所以我对 C++ 中当前的最佳实践和常见设计模式很感兴趣.考虑以下部分示例:

I've spent the last 4 years in C# so I'm interested in current best practices and common design patterns in C++. Consider the following partial example:

class World
{
public:
    void Add(Object *object);
    void Remove(Object *object);
    void Update();
}

class Fire : Object
{
public:
    virtual void Update()
    {
        if(age > burnTime)
        {
            world.Remove(this);
            delete this;
        }
    }
}

在这里,我们有一个负责管理一组对象并定期更新它们的世界.火是一种可能在许多不同情况下添加到世界中的对象,但通常是由世界上已有的另一个对象添加的.火是唯一知道它何时烧毁的对象,所以目前我让它自行删除.引起火灾的物体可能不再存在或不相关.

Here we have a world responsible for managing a set of objects and updating them regularly. Fire is an an object that might be added to the world under many different circumstances but typically by another object already in the world. Fire is the only object that knows when it has burned out so currently I have it deleting itself. The object that created the fire is likely no longer in existence or relevant.

这是明智的做法还是有更好的设计来帮助清理这些物体?

Is this a sensible thing to do or is there a better design that would help clean up these objects?

推荐答案

这样做的问题在于,您实际上是在创建对象和 World 类之间的隐式耦合.

The problem with this is that you're really creating an implicit coupling between the object and the World class.

如果我尝试在 World 类之外调用 Update(),会发生什么?我可能最终会删除对象,但我不知道为什么.责任似乎错综复杂.当您在编写此代码时没有想到的新情况下使用 Fire 类时,这将导致问题.如果应该从多个地方删除对象,会发生什么情况?也许它应该从世界、当前地图和玩家的库存中移除?您的 Update 函数会将其从世界中移除,然后删除该对象,下次地图或清单尝试访问该对象时,就会发生坏事.

If I try to call Update() outside the World class, what happens? I might end up with the object being deleted, and I don't know why. It seems the responsibilities are badly mixed up. This is going to cause problems the moment you use the Fire class in a new situation you hadn't thought of when you wrote this code. What happens if the object should be deleted from more than one place? Perhaps it should be removed both from the world, the current map, and the player's inventory? Your Update function will remove it from the world, and then delete the object, and the next time the map or the inventory tries to access the object, Bad Things Happen.

一般来说,我会说 Update() 函数删除它正在更新的对象是非常不直观的.我还想说一个对象删除自己是不直观的.对象应该更有可能有某种方式来触发一个事件,说它已经完成燃烧,任何感兴趣的人现在都可以对此采取行动.例如,将其从世界中移除.要删除它,请考虑所有权.

In general, I'd say it is very unintuitive for an Update() function to delete the object it is updating. I'd also say it's unintuitive for an object to delete itself. The object should more likely have some kind of way to fire an event saying that it has finished burning, and anyone interested can now act on that. For example by removing it from the world. For deleting it, think in terms of ownership.

谁拥有该对象?世界?这意味着只有世界才能决定物体何时死亡.只要世界对对象的引用比对它的其他引用的持续时间更长,那就没问题了.你认为对象拥有自己吗?那有什么意思?当对象不再存在时,是否应该删除该对象?没有意义.

Who owns the object? The world? That means the world alone gets to decide when the object dies. That's fine as long as the world's reference to the object is going to outlast an other references to it. Do you think the object own itself? What does that even mean? The object should be deleted when the object no longer exists? Doesn't make sense.

但是如果没有明确定义的单一所有者,则实现共享所有权,例如使用实现引用计数的智能指针,例如boost::shared_ptr

But if there is no clearly defined single owner, implement shared ownership, for example using a smart pointer implementing reference counting, such as boost::shared_ptr

但是在对象本身上有一个成员函数,它被硬编码以从一个特定列表中删除对象,无论它是否存在于那里,以及它是否也存在于任何其他列表中,并且不管存在哪个引用都删除对象本身,这是一个坏主意.

But having a member function on the object itself, which is hardcoded to remove the object from one specific list, whether or not it exists there, and whether or not it also exists in any other list, and also delete the object itself regardless of which references to it exist, is a bad idea.

这篇关于对象应该在 C++ 中删除自己吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆