此问题已在此处有答案:
How to initialize static members in the header [duplicate](7个回答)
How can you define a static data member of type const std::string?(11个答案)
How to initialize private static data members in a header file(18回答)
8天前关闭
在非模板化库类中拥有静态成员,而不将定义成员的负担放在类用户身上的最佳方法是什么?
假设我想提供这个类:
class i_want_a_static_member
{
static expensive_resource static_resource_;
public:
void foo()
{
static_resource_.bar();
}
};
然后类的用户一定不要忘记在某处定义静态成员(已经是answeredmanytimes):
// this must be done somewhere in a translation unit
expensive_resource i_want_a_static_member::static_resource_;
下面我有一个答案,但它有一些缺点。是否有更好和/或更优雅的解决方案?
3条答案
按热度按时间2skhul331#
C++17及以上
使用
inline static
变量进行非动态初始化:否则使用函数局部静态变量:
C++14及以下
使用函数局部静态,因为它们更容易使用。
如果出于某种原因,你真的想要一个静态的 * 数据成员 *,那么你可以使用模板技巧:
本地静态
对于需要动态初始化的资源,最好使用本地静态。
文件作用域或类作用域静态数据的动态初始化顺序是未定义的,一般来说,当你试图读取一个未初始化的静态数据作为另一个静态数据的初始化的一部分时,会导致静态数据顺序失败。本地静态解决了这个问题,在第一次使用时被惰性地初始化。
然而,使用局部静校正会有一些轻微的开销。从C++11开始,初始化要求是线程安全的,这通常意味着任何访问都由原子读取和良好预测的分支进行门控。
ssm49v7z2#
我自己的解决方案是使用一个模板化的保持器类,因为静态成员在模板中工作得很好,并将此保持器用作基类。
现在使用保持器类:
但是由于成员的名称是在保持器类中指定的,因此不能对多个静态成员使用同一个保持器。
2nbm6dog3#
在C++ 17。你现在可以使用内联变量来实现这一点: