一旦我阅读了一个很棒的C++ 常见问题解答(真的很好!!)并阅读了有关如何防止静态初始化命令“惨败”的主题。所以作者建议将静态变量包装成函数,从而通过维护变量的创建顺序来防止“惨败”。但这在我看来是一个粗鲁的解决方法。所以我的问题是,是否有任何现代的、更面向模式的方法来防止这种“惨败”,而是将“静态的东西”包装到函数中???
3 回答
现代的、更面向模式的方式是首先不使用全局变量。
没有其他方法可以解决它。
否则,这不会是一场“惨败”!
所以我的问题是,是否有任何现代的、更面向模式的方法来防止这种“惨败”,而是将“静态的东西”包装到函数中???
在大多数情况下,您可以在主函数中声明您的“全局”数据,并在需要时使用依赖注入来传递它。换句话说,根本没有静态。
在实践中,您可能会遇到需要静态数据的情况。如果对其他静态没有依赖关系,则制作静态数据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%?)静态/全局/共享数据应该依赖注入到它使用的地方,而不是创建为静态的。
在极少数情况下,当出于某种原因需要静态并且它们不依赖于其他静态时,请声明静态变量。
在极少数情况下,当静态需要是静态的并且它们相互依赖时,请在静态方法中对它们进行交换。
根据经验,如果您有很多第二种和第三种情况,那么您在第一种情况下做得还不够。
The more usual way of addressing the problem is to avoid statics whenever possible - and even more so between objects that rely on construction order.
Then construct objects in the required order. For example, if we have two objects x and y, and construction of y will fail if x has not been constructed, then construct x first and supply it to the constructor (or another member) of y)
SomeObject x;
SomeOtherObject y(x);
or
SomeObject *x = new SomeObject;
SomeOtherObject y = new SomeObject(*x);
(both of the above assume the constructor of y
requires a reference).
If you need to share x
and y
between functions, simply pass them to functions as arguments.
If you must use statics (i.e. you don't want the typing of passing arguments everywhere) make the statics to be pointers, and initialise them once (for example, in 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;
}
But, really, it is best to avoid using statics if at all possible.