一旦我正在阅读一个非常棒的C++常见问题解答(它真的很棒!! https://isocpp.org/faq)并阅读了有关如何防止静态初始化顺序“失败”的主题。所以作者建议将静态变量包含到函数中,从而通过维护变量的创建顺序来防止“失败”。但这在我看来似乎是一个粗鲁的解决方法。所以我的问题是,是否有任何现代的,更模式化的方式来防止这种“惨败”,而是将“静态的东西”封装到函数中?防止静态初始化顺序“失败”,C++
7
A
回答
8
1
解决此问题的更常见方式是尽可能避免静态 - 在依赖构造顺序的对象之间更是如此。
然后按需要的顺序构建对象。例如,如果我们有两个对象的x和y,和y的结构,如果x没有构成将失败,则第一构造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;
}
但是,如果可能的话,最好避免使用静力学。
2
所以我的问题是,是否有任何现代的,更多的面向模式的方式来防止这种“惨败”,而是将“静态的东西”包装到函数中?
在大多数情况下,您可以在主函数中声明您的“全局”数据,并在需要时使用依赖注入传递它。换句话说,根本没有静态。
在实践中,您可能会遇到需要静态数据的情况。如果与其他静态数据不存在依赖关系,则使用静态数据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。作为一个经验法则,如果你有很多的第二和第三种情况,你没有做足够的第一个。
相关问题
- 1. C++静态初始化命令失败
- 2. C++静态初始化顺序
- 3. 静态初始化顺序失败:相同的编译单元?
- 4. 静态顺序初始化惨败,的iostream和C++ 11
- 5. 防止静态库被初始化
- 6. 静态QString初始化失败
- 7. 静态初始化顺序的悲剧
- 8. 静态变量初始化顺序
- 9. 静态成员java初始化顺序
- 10. 静态变量的初始化顺序
- 11. 再论用C静初始化顺序++
- 12. C++静态常量和初始化(有没有一个失败)
- 13. 静态块VS中的静态变量初始化顺序
- 14. direct3d初始化失败/ C++
- 15. 静态初始化C++
- 16. C++静态简单类型是按顺序初始化的吗?
- 17. C++单初始化顺序
- 18. 静态初始化
- 19. Objective C中的静态初始化C
- 20. 如何防止Hikari池初始化失败,如果数据库连接失败
- 21. 如何防止静态方法中静态字段的多重初始化?
- 22. 静态初始化的Java序列化
- 23. 静态const模板成员初始化失败,MSVC
- 24. 失败隐式静态成员初始化由Visual Studio
- 25. 属性文件的静态初始化失败,并生成ant
- 26. 解决静态初始化命令失败
- 27. Java是否有静态命令初始化失败?
- 28. iOS初始化一个静态对象的成员失败
- 29. Caffe是否包含静态初始化失败?
- 30. 一类中静态初始值设定项的初始化顺序
防止失败的优雅方法是永远不要使用依赖于任何东西的静态对象。 – user2079303
常见问题解答建议*建立在首次使用习语*上。对许多C++程序员来说,它是一种类似的模式。实施起来很简单,甚至更简单。我看不出“现代,更多以模式为导向”的意思。 –
另请参阅[AddressSanitizerInitializationOrderFiasco](https://github.com/google/sanitizers/wiki/AddressSanitizerInitializationOrderFiasco)。 – jww