作为示例,让我们讨论使用new
(在第一次调用getInstance()
方法时创建实际实例而不是使用静态字段的实现单例实现。我突然意识到它从来没有释放过那些记忆。但是再一次,它必须在应用程序关闭之前做到这一点,所以系统将释放内存。
除了糟糕的设计,这种方法有哪些实际缺点?
编辑:广告评论 - 所有有效点,谢谢你们。那么让我问一下 - 对于单线程应用和POD单例类是否有任何实际的缺点?从理论上讲,我实际上不会这样做。
答案 0 :(得分:0)
对于单线程应用和POD单例类有任何实际缺点吗?从理论上讲,我实际上不会这样做。
in standardese
[c ++ 14-Object lifetime-4]对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数;但是,如果没有显式调用析构函数或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何程序都依赖于析构函数产生的副作用有未定义的行为。
其中dtor隐式调用自动/静态变量等。
所以,(假设一个新的表达式用于构造对象),被调用的分配函数的运行时实现可以自由释放内存并让对象在遗忘中衰减,只要没有可观察的效果取决于它的破坏(这对于具有微不足道的dtors的类型来说是微不足道的。)
答案 1 :(得分:0)
对所有单例类型使用schwartz计数器。这是std::cout
的实施方式。
优点:
线程安全
当单身人士相互依赖时,保证正确的初始化顺序
程序终止时正确的销毁订单
不使用堆
100%符合c ++ 98,c ++ 03,c ++ 11,c ++ 14,c ++ 17 ......
不需要丑陋的getInstance()函数。只需使用全局对象。
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
至于标题问题:
在程序结束前没有释放内存有多糟糕?
当程序在管理进程内存的操作系统下运行时,不释放内存并不是那么糟糕。
但是,单身人员所做的其他事情可能包括刷新IO缓冲区(例如std::cout
,std::cerr
)。这可能是你想避免失去的东西。