2010-09-29 84 views
7

我听说使用静态成员对象不是一个很好的做法。在类中使用静态成员对象有什么问题?

比方说,我有这样的代码:

class Foo { 
... 
static MyString str; 
}; 

我定义和这个类作为实施文件初始化这个变量:

MyString Foo::str = "Some String"; // This is fine as my string API handles this. 

当我运行这段代码,我得到警告:

warning:'Foo::str' requires global construction. 

我在班上有很多这样的成员,处理这个问题的最好方法是什么?秒。

感谢,

回答

10

大部分反对它们的论点与全局变量相同:

  1. 不同编译单元之间的初始化顺序未定义。
  2. 在一个编译单元内的初始化顺序可能会影响行为—因此可能需要非平凡顺序。
  3. 如果一个构造函数抛出一个异常,你不能捕获它,你的程序将被终止。

附录:要正确处理这个问题,您必须确保上面的点不适用于您的代码并忽略警告或重新设计您的程序:您是否真的需要它们是静态的?为什么不使用const char* Foo::str = "Some String";

+0

虽然我很欣赏你的列表,但大部分都是实现细节。从功能角度来看,这也会影响再入行,从而影响可测试性和多线程程序。 – 2010-09-29 14:02:27

2

使用静态成员,你不能保证线程安全,想像两个线程试图访问静态成员 - 现在这将是该成员的价值 - 是从线程X中的一个或线程y,这也引发了另一个副作用,竞态条件,其中一个线程在另一个线程完成之前修改静态成员...换句话说,使用静态成员可能是危险的...

+4

不仅对静态成员而且对于线程之间的任何共享数据都是如此。我认为这不能正确回答问题,因为线程安全性与静态成员初始化无关。 – ybungalobill 2010-09-29 12:49:44

3

此示例所关注的最大原因是构建静态成员对象发生在main()之前,销毁发生在main()之后(或者您致电exit())。到目前为止,这是一件好事。但是当你的程序中有多个这样的对象时,你可能会冒代码尝试使用尚未构造或已被销毁的对象的错误。

关于此主题的C++ FAQ Lite有some helpful discussion,包括解决方法。推荐读物是问题10.14至10.18。 10.17最直接适用于你的例子。

1

作为一个例子,它需要知道一个类的实例数量。这需要类静态成员来跟踪实例的数量。

如果问题解决方案需要这样的设计,那么拥有类的静态成员没有任何问题。正如其他职位中提到的那样,必须小心谨慎。

相关问题