今天我的一个朋友问我,为什么他应该更喜欢使用单过全局静态对象? 我的方式开始它来解释是,单可以有状态与静态全局对象不会......但后来我不是在C ++ sure..because这个..(我是从C#来)
有什么优势了另一种? (在C ++)
今天我的一个朋友问我,为什么他应该更喜欢使用单过全局静态对象? 我的方式开始它来解释是,单可以有状态与静态全局对象不会......但后来我不是在C ++ sure..because这个..(我是从C#来)
有什么优势了另一种? (在C ++)
实际上,在C ++优选方式是局部静态对象。
Printer & thePrinter() {
static Printer printer;
return printer;
}
这在技术上是一个单身,虽然,这个功能甚至可以是一个类的静态方法。 因此,担保将建造不像全局静态对象之前使用,可以在任何顺序创建,使得当一个全局对象使用另一个,一个相当普遍的情况下,可以unconsistently失败。
是什么使得它比通过调用创建新实例做单身常见的方式更好的new
是对象的析构将在节目结束时调用。 它不会与动态分配的单身发生。
另一个积极的方面是没有办法访问单被创建之前,即使是从其他静态方法或从子类。 节省您的一些调试时间。
在C ++中,静态对象的实例化在不同的编译单元的顺序是不确定的。 因此,有可能为一个全局引用另一个未建立,炸毁你的程序。 单例模式中删除由捆扎结构到一个静态成员函数或免费功能这一问题。
有一个像样的总结在这里 。
今天我的一个朋友问我,为什么他应该更喜欢使用单过全局静态对象? 我的方式开始它来解释是,单可以有状态与静态全局对象不会......但后来我不是在C ++ sure..because这个..(我是从C#来)
静态全局对象可以在C#中的状态,以及:
class myclass {
// can have state
// ...
public static myclass m = new myclass(); // globally accessible static instance, which can have state
}
有什么优势了另一种? (在C ++)
一个单身削弱你的代码,一个全球性的静态实例没有。 有关于与已经单身的问题上SO无数的问题。 这里有一个 , 而另一个 , 或其他 。
总之,单身给你两件事情:
如果我们只是第一点,我们应该创建一个全局可访问的对象。 为什么会我们曾经希望第二个? 我们事先不知道怎么我们的代码可能在将来被使用,那么为什么钉下来,并删除了可能是有用的功能? 我们通常是错误的 ,当我们预测,“我只需要一个实例。” 还有的与“我只需要一个实例”(正确答案是再创建一个实例),以及“应用程序不能在任何情况下,如果正确创建多个实例上运行,它会崩溃很大的区别,格式化用户的硬盘并发布在互联网上的敏感数据”(这里的答案则是:最有可能您的应用程序被打破,但如果不是,那么是的,单身是你所需要的)
在全局静态对象的辛格尔顿的另一个好处是,因为构造函数是私有的,有一个非常明确的,编译器执行指令说:“只能有一个。”
相比较而言,与全球静态对象,会有什么能够阻止创建该对象的其他实例开发者编写代码。
额外的约束的好处是,你必须保证的对象将被如何使用。
原因1:
单身是很容易的使他们懒惰的构建。
虽然你可以做到这一点与全局它由开发商承担额外的工作。 因此,通过默认全局总是被初始化(除了使用命名空间的一些特殊的规则)。
所以,如果你的对象是大型和/或昂贵的打造你可能不希望构建它,除非你真的要使用它。
原因2:
初始化(和销毁)问题的顺序。
GlobalRes& getGlobalRes()
{
static GlobalRes instance; // Lazily initialized.
return instance;
}
GlobalResTwo& getGlobalResTwo()
{
static GlobalResTwo instance; // Lazy again.
return instance;
}
// Order of destruction problem.
// The destructor of this object uses another global object so
// the order of destruction is important.
class GlobalResTwo
{
public:
GlobalResTwo()
{
getGlobalRes();
// At this point globalRes is fully initialized.
// Because it is fully initialized before this object it will be destroyed
// after this object is destroyed (Guaranteed)
}
~GlobalResTwo()
{
// It is safe to use globalRes because we know it will not be destroyed
// before this object.
getGlobalRes().doStuff();
}
};
使用辛格尔顿成语(“在首次使用时建”),你能避免静态初始化顺序的悲剧
在C ++中,有没有两者之间的差异在实际应用来看,数额巨大。 全局对象当然可以维护自己的状态(可能与其他的全局变量,虽然我不建议这样做)。 如果你要使用全局或单(也有很多理由不来),使用单过一个全局对象的最大理由是,一个单身,你可以有几类继承具有动态多态性一个单基类。
OK,有两个原因去与一个单身真的。 一个是静态的顺序事情大家都在谈论。
另一种是防止有人使用您的代码时,做这样的事情:
CoolThing blah;
gs_coolGlobalStaticThing = blah;
或者,更糟糕的:
gs_coolGlobalStaticThing = {};
封装方面将保护白痴和恶意抽搐您的实例。