一旦我读了一篇很棒的C++ FAQ(这真的很棒!!)并阅读了topic关于如何防止静态初始化命令" fiasco"。因此作者建议将静态变量包装到函数中,从而防止" fiasco"通过维护变量的创建顺序。但在我看来,这是一个粗鲁的解决方法。所以我的问题是,是否有任何现代的,更加模式化的方式来防止这种惨败"但要包装"静态东西"进入功能???
答案 0 :(得分:12)
现代的,更注重模式的方式是不首先使用全局变量。
没有别的办法了。
它不会成为"惨败"否则!
答案 1 :(得分:2)
所以我的问题是,是否有任何现代的,更多模式导向的方法来防止这种“惨败”,但将“静态东西”包装成函数???
在大多数情况下,您可以在main函数中声明“全局”数据,并在需要时使用依赖注入来传递它。换句话说,根本没有静态。
实际上,您可能会遇到需要静态数据的情况。如果没有其他静态的依赖项,请创建静态数据const/constexpr
。
// smart pointer that implements the "Foo" release policy
class FooPointer
{
static const FooPointer NullFoo; // does not depend on other static values
/* ... */
};
如果静态变量做相互依赖,只需将它们包装在静态函数中:
// smart pointer that implements the "Foo" release policy
class FooPointer
{
static const FooPointer& NullFoo(); // depends on other static values
/* ... */
};
总结:
大多数(90%?99%?)静态/全局/共享数据应该依赖注入到它的使用位置,而不是根据静态创建。
在极少数情况下,由于某种原因需要静态而且它们不依赖于其他静态,请声明静态变量。
在非常罕见的情况下,当静态需要是静态的并且它们相互依赖时,用静态方法对它们进行wap。
根据经验,如果你有很多第二和第三种情况,你在第一种情况下做得不够。
答案 2 :(得分:1)
解决问题的更常用方法是尽可能避免静态 - 在依赖施工顺序的对象之间更是如此。
然后按所需顺序构造对象。例如,如果我们有两个对象x和y,如果没有构造x,y的构造将失败,那么先构造x并将其提供给y)的构造函数(或其他成员)
SomeObject x;
SomeOtherObject y(x);
或
SomeObject *x = new SomeObject;
SomeOtherObject y = new SomeObject(*x);
(以上两者都假设y
的构造函数需要引用)。
如果您需要在函数之间共享x
和y
,只需将它们作为参数传递给函数。
如果你必须使用静态(即你不想在任何地方输入传递参数)使静态成为指针,并初始化它们一次(例如,在main()
中)。
// all source files can use x and y via these declarations (e.g. via a header file)
extern SomeObject *x;
extern SomeOtherObject *y;
// definition in one source file only
SomeObject *x;
SomeOtherObject *y;
int main()
{
x = new SomeObject;
y = new SomeOtherObject(*x);
// call other functions that use x and y.
delete y;
delete x;
}
但是,实际上,如果可能的话,最好避免使用静态。