销毁单件对象的最佳方法是什么?
案例A:单线程环境
案例B:多线程环境
示例代码段(如果有)将非常有用。
[编辑]我没有特定的用例我只是想了解如果必须使用所有单例如何正确销毁它。据我了解,从评论中可以看出两种情况:
1.当没有代码访问它时销毁单例。(使用智能指针,它将负责使用RAII自行销毁对象)
2.退出程序时销毁单例,无论某些代码是否持有单例。
(通过在主要退出之前删除实例来明确销毁)
答案 0 :(得分:9)
首先不要创建它!
说真的,我强烈建议您重新考虑您对单例的选择,尤其是在多线程环境中。相反,只需在main()
中创建一个实例,然后将其传递给调用层次结构,直到需要它为止。
您可以使用类似shared_ptr
的内容来确保对象保持不变,直到没有人再需要它为止。
答案 1 :(得分:2)
如果您只关心清理成功停机,可以使用atexit()。
答案 2 :(得分:1)
在多线程中,
void Singleton::Destroy()
{
if (instance) {
pthread_mutex_lock(&lock);
if (instance) {
delete instance;
instance = 0x0;
}
pthread_mutex_unlock(&lock);
}
}
在单线程中:
void Singleton::Destroy()
{
if (instance) {
delete instance;
instance = 0x0;
}
}
答案 3 :(得分:1)
对过去十年过度使用单身人士的强烈反对似乎是粗暴的健康,但他们并非完全邪恶或不合理......编程是妥协和实践,而且很难概括(通常;-P) 。通过各种方式重新审视设计,看看你是否可以有效地摆脱它们,但如果没有 - 那就这样吧。
无论如何,如果你想了解权衡,你最好不要先阅读Alexandrescu的现代C ++设计,该设计专门讨论单身人士的替代方案。基本上,你在这里问一个愚蠢的问题,因为我们不知道你的单身人员有什么操作限制......他们可能需要使用哪些潜在的互动,以及他们是否可以在关闭后重新打开等等。所以,吐出来或满足于愚蠢的答案;-P。
答案 4 :(得分:1)
不考虑这是不是一个好主意的问题 我们应该在一个单独的问题中做什么!
class S
{
private:
S() {} // private constructor
S(S const&); // Undefined copy constructor
S& operator(S const&) // Undefined assignment operator
public:
static S& getInstance()
{
/*
* It is guaranteed to be built on first use
* and correctly destroyed at the end of the application
*/
// Need guard for multi-threaded systems (but not on gcc)
MULT_THREAD_GUARD;
static S theOnlyInstance;
return theOnlyInstance;
}
};
对象的多线程初始化是唯一真正的问题。你可以用这两种方式处理。
守卫示例
// Then in your platform agnostic header file
#ifndef MULTI_THREAD
#define MULT_THREAD_GUARD /* Nothing needed in single threaded code */
#else
#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 3 ) && (__GNUC_MINOR__ > 1)))
#define MULT_THREAD_GUARD /* Nothing required for GCC 3.2 onwards */
#elif defined(YOUR_COMPILERS_MACRO)
#define MULT_THREAD_GUARD do { /* Put compiler lock code here */ } while (false)
#else
#error "ADD MULTI Thread GUARD for you compiler here"
#endif
答案 5 :(得分:1)
如果你打算使用全局,我更喜欢这样的东西:
class GlobalThing{ /* ... */ };
GlobalThing *global_thing = 0;
// ...
int main(){
GlobalThing gt(/* ... */);
global_thing = >
// create threads
// ...
// kill threads
}
这会给你:
你仍然需要担心: