English 中文(简体)
你如何选择单例模式和匿名类?
原标题:
  • 时间:2008-12-28 01:58:05
  •  标签:

我会像这样使用单例:

Singleton* single = Singleton::instance();
single->do_it();

我会用一个未命名的类来做这件事:

single.do_it();

我觉得单例模式除了具有可读的错误消息之外,没有比未命名类更大的优势。使用单例比使用未命名类对象更加笨拙:首先,客户端必须先获取实例的句柄;其次,实现者Singleton::instance()可能需要考虑并发问题。

那么,为什么会选择单例模式,而不是匿名类?

附言,尽管未命名类的明显定义可能是

class {
    // ...
}single;

我也可以这样定义它:

#ifndef NDEBUG
class Singleton__ {   // readable error messages,
#else
class {               // unnamed, clients can t instantiate
#endif
    // ...
}single;

后一种方法具有易读的编译器错误消息的优点,但在 Debug 模式下不是单例。

最佳回答

我认为最重要的原因是,您不能在命名空间范围内放置一个未命名的类。因此,以下内容无效(gcc接受,但发出警告。Comeau在严格模式下不接受):

class { } single;
int main() { }

single类型没有外部联系,因为没有办法在其他范围内声明其名称并引用它(因为它没有名称)。但是使用它来声明具有外部链接的single是无效的(3.5/8)。single必须在主函数中本地定义,这样它将没有链接。您也不能将单个传递给函数模板,并且它无法具有静态数据成员(因为无法定义它们)。所有这些限制使它更或多或少不适用于替代单例。

问题回答

在C++中使用单例对象的主要原因无疑是通过在实例方法中使用惰性构建,使您对初始化顺序有一定的控制?

作为一个例子,我的很多代码都使用一个记录器单例,其中写入日志消息。这始于很久以前的一个好老的全局变量,但在尝试在构建之前使用它时被咬伤后,它现在是一个单例模式:

I'm sorry, I cannot translate without context. Please provide me with more information.

logger.write("Something bad happened..."); // crash if logger not constructed

之后

 Logger &getLogger()
 {
   static Logger logger_;
   return logger_;
 }

 getLogger().write("Something bad happened...");

我读过关于“单例模式不好”的普通帖子,但没看到有人为C++提出更好的替代方案。

你可以在头文件中声明单例类并在CXX文件中实现,因此可以在CXX文件中共享。但是对于未命名的类,由于每个CXX都会尝试拥有自己的对象实例,因此无法这样做。

即使那样更改代码可能不应该影响代码生成,但这是一个可怕的想法。 迟早有一天,有人会进行微小的调整,在调试或发布中生成不同的代码,然后您就会面临发布崩溃的难题,而无法在调试版本中重现。

尽管方便,单例通常是一个坏主意。请参见此页面以获取替代设计。

从您的提问中我可以看出您并不真正理解单例模式的本质和目的。

You use singleton if you want to have global object accessible by many clients and you want to be sure only one instance of this object is created. Take for example a logger object. You want to be able to log from any part of your code but there should be only one logger in your project. This is a perfect place for singleton.

你的示例看起来像是创建了一个范围较小的本地对象。因此,不需要使用单例模式。尽管如此,这样做可以使代码更加清晰易读。

如果(除了错误冗长度之外)没有行为差异,全局实例需要额外的1行代码,单例将需要一堆非常繁琐的样板代码。简单明了原则。

使用单例模式。使用常量。在一个神类中初始化它们全部。注意并避免静态初始化顺序混乱的问题: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12





相关问题
热门标签