问题:我应该为具有程序范围的单例编写析构函数(在程序启动时生效并在程序结束时死亡)
明细:
我处于两难境地
“我应该为单身人士课程编写析构函数吗?”
1)这个类有程序范围 2)类在堆上使用大量内存,因此释放需要时间
当用户退出程序时,响应速度应该很快,那么为什么要花时间释放这个单例所占用的内存,因为当程序结束时会释放内存。
答案 0 :(得分:3)
如果释放内存需要很长时间,请不要这样做。这可能是一个大而耗时的问题,特别是如果释放内存导致大量缓存未命中。操作系统将完成这项工作(当然,如果您在实际执行此操作的系统上运行)。
但是,如果析构函数确定了某些资源(例如,解锁文件或硬件),并且使用“资源获取是初始化”,则必须确保调用正确的析构函数(例如,在main()
函数返回后调用静态对象。 如果你的单例内部分配的某些对象也锁定了资源,那么这就行了!
因此,在大多数情况下,最好为这样的对象实际编写析构函数并使其释放内存可选。
SSS决定不写下析构函数。但是,我想再多说一点,这不是最好的解决方案。
不释放静态对象的内存(让我们称之为“静态”)是一种非常微妙的优化,它与常识以及人们通常如何编写程序相矛盾。你的代码,分配内存,只是没有析构函数,看起来很奇怪。同行会认为这个班级编写得很糟糕,往往会看到错误(当他们在另一个班级时)。
相反,您应该遵循通用编码标准,这些标准规定C ++中的内存管理应该是正确的。写一个析构函数,并且只有在它显示它有一个显着的提升而不是解除分配之后,包装它的代码不被调用。
不释放内存的意图必须是显式。
MySingleton::~MySingleton()
{
#ifndef RELEASE
// The memory will be released by OS when program terminates!
delete ptr1;
delete ptr2;
#endif
}
甚至
MySingleton::~MySingleton()
{
// We don't do anything here.
// The memory will be released by OS when program terminates!
}
但是析构函数最好坚持下去。
答案 1 :(得分:2)
听起来你正在创建一个God Object,所以重新考虑你班级的设计可能会有所帮助。
是否添加析构函数取决于是否值得释放性能并最终重新分配内存。
答案 2 :(得分:2)
C ++语言不保证在程序终止时回收内存,但任何一半体面的操作系统都会毫无问题地进行回收。
是的,如果
然后是的,你可以省略析构函数,泄漏内存,并依赖操作系统来清理你。
明显的缺点是各种调试工具可能会尖叫并对内存泄漏大吼大叫。
当然,一个稍微更基本的问题是为什么要创建一个分配那么多内存的单例?
这对我来说听起来很糟糕。
答案 3 :(得分:2)
以正确的方式实现析构函数,并且是最易维护的版本。然后测量(创建一个只创建单例并退出的可执行文件)释放内存所需的实际时间。
在确定正确删除成本的确凿事实之后,请不要编写错误的代码。如果需要一些可测量的时间,请将其视为相对于程序运行时间的相对度量。在大多数情况下,应用程序所需的处理将远远超过释放内存所需的时间。
如果您仍然认为需要花费太多时间,请考虑一下普通用户会考虑太多时间,用户打开和关闭应用程序的次数,如果它确实相当于任何东西。
如果最后你认为它太多了,你冒的风险是,在以后的某个时间内应用程序将被修改,单例可以获取外部资源而不是释放它们 - 这对于文件锁特别糟糕。
那些牺牲表现正确性的人不应该
答案 4 :(得分:0)
如果您在Windows操作系统下运行,当应用程序关闭时,任何进程占用的所有内存/资源都将被回收,因此恕我直言无关紧要
答案 5 :(得分:-2)
正如所指出的那样,操作系统应最终释放内存,但是你真的想信任它来管理吗?至少在显式破坏的情况下,一个错误/设计糟糕的内存管理器有更多的机会来实现它。
它有两次机会让它正确。