2

我有以下结构(简化):

class myType
{
    static char* data;
    //more private data here
public:
    //public interface here
};

data是所有实例之间共享的资源myType,它指向动态分配的内存(由其中一个实例在初始化时分配)。

到目前为止,一切都很好。当我需要释放data. 引用计数在这里不是一个解决方案,因为在某个执行点没有单个实例是有效且可能的情况myType- 稍后可以创建一个新实例 - 因此data必须持续存在。

我需要在驱动程序卸载时释放该内存,但卸载与myType对象的实际销毁无关,因此我被迫data手动释放。这是可以接受的,但是data(并且应该)private并且无法从卸载处理程序访问。当然,我可以在里面创建一个staticandpublic destroy函数,myType但这似乎不对——毕竟我不需要public初始化器,那么为什么我需要一个来释放内存呢?不应从外部myType实例访问该数据。

我将不胜感激有关该主题的任何见解。

4

3 回答 3

3

根据您的代码的复杂性,我更喜欢以下两种选择之一:

  1. 有一个静态公共destroyMetadata方法,如果在执行过程中创建了任何实例,则需要调用该方法。就我个人而言,我认为有一种方法可以销毁隐式创建的数据并没有什么特别不好的地方。这种方法的问题在于它是一种手动方法,因此有点容易出错
  2. 创建一个(单例)卸载处理程序,您可以在其中注册要在清理时执行的回调。然后,您可以创建一个私有静态方法,并在首次创建destroyMetadata时将其注册到处理程序。data这需要更多的努力,但总体上会产生更清洁的设计。

这两者中哪一个适合您取决于您​​的清理工作可能变得多么复杂。如果您有几十个具有自定义清理的类,则第二个选项似乎更可取,因为它可以产生更好的封装和更简洁的代码。但是,如果这是您的代码的唯一部分,您需要进行此类清理,那么编写这样的通用处理程序 (YAGNI) 有点矫枉过正,所以第一种方法虽然在概念上更混乱,但在这种情况下看起来要好得多。

于 2013-05-05T10:56:51.750 回答
1

不需要公共初始化程序来分配它与释放它无关——在第一次使用时分配它是微不足道的,因为你运行的代码知道它需要在那里(如果 (data==NULL) data=new. ..),但是如果这在您的析构函数中没有意义,那么如果您想确保返回内存,则可能需要一个公共解除分配器。

另一种可能性(如果在您的情况下有意义)是在构造函数中增加引用计数并在析构函数中减少引用计数,但是当计数达到零时,不要立即解除分配。相反,那时您可以设置一个计时器以在某个“冷却”期后解除分配。如果在此计时器触发之前调用构造函数(或其他延迟分配内存的代码),则取消计时器而不是重新分配,但如果计时器触发,它将解除分配。

于 2013-05-05T10:54:58.810 回答
1

我不明白为什么public static破坏功能似乎不正确。正如您自己争论的那样,所需的破坏时刻与对象及其实例本身的生命周期之间没有关系。因此,您将及时销毁外部实体的责任,然后逻辑上需要能够访问它。在这种情况下,这种public static方法最有意义。这种方式有点像一个瘦垃圾收集器。

我认为底层架构是有缺陷的,它需要你做出这个决定,并且数据容器应该是一个单独的正确引用计数的类,具有适当的生命周期控制和一个真正的垃圾收集器,但这取决于代码的其余部分。所描述的解决方案可能是最好的。

于 2013-05-05T10:55:12.587 回答