使用指针和使用静态对象实现单例实现之间的区别
Difference between Singleton implemention using pointer and using static object
编辑:对不起,我的问题不清楚,为什么书/文章更喜欢实施#1而不是实施#2?
?使用静态对象使用指针在实现Singleton类VS方面的实际优势是什么?为什么大多数书都喜欢这个
class Singleton
{
private:
static Singleton *p_inst;
Singleton();
public:
static Singleton * instance()
{
if (!p_inst)
{
p_inst = new Singleton();
}
return p_inst;
}
};
在这个
上class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
protected:
Singleton(); // Prevent construction
Singleton(const Singleton&); // Prevent construction by copying
Singleton& operator=(const Singleton&); // Prevent assignment
~Singleton(); // Prevent unwanted destruction
};
为什么书/文章更喜欢实施#1而不是实施#2?
因为大多数描述Singleton AntiPattern的文章在试图在C 中安全实施时,并不完全理解所有隐藏的危险。做对了很难。
使用静态对象使用指针在实现单例类VS方面的实际优势是什么?
使用指针,带有new
,但没有delete
,可以确保对象永远不会被破坏,因此在其寿命结束后没有访问它的危险。结合"懒惰"的创建,第一次访问它,这可以确保所有访问权限均为有效对象。缺点是创建不是线程安全,并且该对象及其获得的任何资源均未在程序结束时发布。
使用本地静态对象,创建是支持C 11线程模型的任何编译器上的线程安全。此外,该对象将在程序结束时被破坏。但是,可以在对象破坏后访问该对象(例如,来自另一个静态对象的损坏器),这可能会导致讨厌的错误。
最好的选择是尽可能避免静态数据和全球可访问的数据。特别是,切勿使用Singleton Anti Pattern;它将全局静态数据与怪异的实例化限制相结合,这使得测试非常困难。
第二版(使用本地静态变量)具有显着优势。
它不需要使用自由商店,因此不会被检测到内存泄漏。它是线程安全(在C++11
中)。它更短,更简单。
唯一的缺点是不可能使其处于Portable threadSafe(对于Pre-C 11编译器),并且它不会为您提供明确销毁Singleton实例的选项。
我始终更喜欢第二个,但是第一个确实具有一些潜在的有趣优势: -
-
清晰度 - 对指针为null的检查有效编译器在构造静态时在引擎盖下做什么对象。从"学习"的角度来看,了解方法中使用静态对象时发生了什么范围。
-
懒惰分配 - 在第一种情况下,单例对象是堆分配。如果您的功能从未运行,则对象永远不会建造,永远不会消耗记忆。但是,在第二种情况下,内存由链接器分配以将对象保存在即使"施工"很懒惰。
第二个示例以" Meyers'Singleton"的名称知道,因为它首先在"有效的C "或"更有效的C "中发布。我不确定哪一个,但两者都是在"设计模式"之后出版的 - 因此,四人的帮派可能同样并不意识到他们的书写时的第二个模式。
另外,第一种方法是其他语言的标准性 - 您可以在Java或C#中进行第一种方法,但第二种方法是,因此来自不同背景的人可能是第一种更名的另一个原因。
在技术方面,您可以通过第一种方法来控制单身人士何时被摧毁,但这也可能会给您带来很多头痛。
第二个具有非确定性破坏。第一个,您可以控制何时删除指针,如果有的话。
当然,第一个构造不是线程安全,但可以使用boost::call_once
(或std::call_once
(如果有))进行
第二个结构足够常见在另一个线程使用它之前完成结构)。
如果破坏顺序没有问题,那么只要您的编译器将其保证为线程安全,就可以继续使用静态版本。
一个优势是您不必检查单身人是否已经实例化。
另一个是您不必担心去分配任何内存。
非本地静态怎么样?有人看到这个问题吗?
class Singleton
{
static Singleton singleton;
Singleton();
// etc
public:
static Singleton &Instance() { return singleton; }
};
Singleton Singleton::singleton;
// etc
- 比较器的两个实现之间的差异
- C++:调用运算符和调用其实现之间有区别吗
- C++ 和 Python 实现之间的不同伪随机数
- 有没有办法根据模板参数的类型在不同的类实现之间进行选择
- 可能的std ::前向实现之间的区别
- 原子衰落实现之间的差异
- STD ::正向实现之间的区别
- 链接列表C 类,这两个添加节点实现之间的差异是什么?
- 优先级队列使用堆 - JavaScript和C 实现之间的差异
- 以下 C++ 结构实现之间的区别
- 使用指针和使用静态对象实现单例实现之间的区别
- 作用域在两个类实现之间不完全独立
- c++中两种形式的专业化模板实现之间的区别是什么
- 为什么我看到两个blowfish实现之间不一致
- 来自 vtable 的未定义符号是否意味着接口和实现之间存在错误
- 使用函数指针在函数实现之间切换
- STL队列(OR堆栈)的deque和链表(+vector)实现之间有什么区别
- 函数原型和C++中的函数实现之间的区别是什么
- 不同实现之间的随机输出不同
- c++提倡类定义和类实现之间的分离,但JAVA没有