代码之家  ›  专栏  ›  技术社区  ›  Etienne Dechamps

如何处理指针成员的不同所有权策略?

  •  1
  • Etienne Dechamps  · 技术社区  · 15 年前

    class Filter
    {
        virtual void filter() = 0;
        virtual ~Filter() { }
    };
    
    class FilterChain : public Filter
    {
        FilterChain(collection<Filter*> filters)
        {
             // copies "filters" to some internal list
             // (the pointers are copied, not the filters themselves)
        }
    
        ~FilterChain()
        {
             // What do I do here?
        }
    
        void filter()
        {
             // execute filters in sequence
        }
    };
    

    我在一个库中公开这个类,所以我无法控制它的使用方式。

    我目前有一些关于所有权的设计问题 Filter 物体 FilterChain :

    • 场景A:我的库中的一些函数正在构造一个(可能很复杂的)过滤器链,根据需要分配内存,并返回一个新分配的 过滤链
    • 场景B:用户可以访问一堆 过滤器 对象,并希望以特定方式在筛选器链中组合它们。用户构造 自己用的东西,等他用完了再销毁。这个 物体 当一个 过滤链 它们被销毁了。

    现在,在 过滤链 对象是:

    • 拥有 物体。这意味着 过滤链 被摧毁在 过滤链 的析构函数。这与场景B不兼容。
    • 拥有 的析构函数什么也不做。现在场景a出现了一个问题,因为用户必须知道所有场景的内部结构 过滤器 对象,以便在不丢失一个的情况下将它们全部销毁,作为父对象 不是自己做的。这只是糟糕的设计,要求内存泄漏。

    过滤器 物体, 过滤链 过滤器 物体。什么时候? 过滤链 的析构函数,它将销毁智能指针。然后,智能指针本身的析构函数将销毁所指向的对象(a) 对象) 当且仅当

    auto_ptr 在这里和这里都没用 shared_ptr 似乎杀伤力太大了。那么,我的解决方案是不是一个好主意?

    4 回复  |  直到 15 年前
        1
  •  3
  •   the_mandrill    15 年前

    这里的智能指针并不过分:很明显,您存在这样或那样的设计问题,需要仔细考虑对象的生命周期和所有权。如果您希望能够在运行时在过滤器图中重新修补过滤器,或者希望能够创建复合过滤器,那么这一点尤其正确 FilterChain 物体。

    使用 shared_ptr Filter 对象由单个类拥有,然后 过滤链 过滤器 物体。

    它的设计非常轻巧。

        2
  •  2
  •   Mark B    15 年前

    FilterChain ? 如果你能做到这一点,那么你所有的问题都会消失 过滤链 总是自己打扫。

    shared_ptr 似乎最有意义。打电话的人必须负责保持联系 共享\u ptr 对于它关心的每个对象 过滤链 将知道是否删除特定的过滤器时,它是 delete

    编辑:正如尼尔所说 Filter 需要一个虚拟析构函数。

        3
  •  0
  •   James Curran    15 年前

    FilterChain DeleteAll() 方法,该方法对集合和 delete 这是过滤器。它 在场景A中调用 不是 在场景B中调用。这确实需要FilterChain用户的一些智能,但不需要记住 删除 反对他们 new

        4
  •  0
  •   Chad Simpkins    15 年前

    我会选择FilterChain而不是拥有Filter对象。然后,在您的库中,当您需要从文件加载FilterChain时,您将拥有另一个Loader对象,它负责Filter对象的生存期。因此,FilterChain将为库加载的链和用户创建的链一致地工作。