在非模板化库类中拥有静态成员的最佳方法是什么,
而不将定义成员的负担强加给类用户?
假设我想提供这个课程:
class i_want_a_static_member
{
static expensive_resource static_resource_;
public:
void foo()
{
static_resource_.bar();
}
};
那么类的用户一定不要忘记在某处定义静态成员
(正如已经answered https://stackoverflow.com/questions/185844/initializing-private-static-members many https://stackoverflow.com/questions/3536372/defining-static-members-in-c times https://stackoverflow.com/questions/1639154/how-to-declare-a-static-const-char-in-your-header-file):
// this must be done somewhere in a translation unit
expensive_resource i_want_a_static_member::static_resource_;
我在下面确实有一个答案,但它有一些缺点。有更好和/或更优雅的解决方案吗?
C++17 及以上
Use inline static
非动态初始化的变量:
struct Foo
{
inline static int I = 0;
};
否则使用函数局部静态变量:
struct Foo
{
static std::string& Bar()
{
static std::string S = compute();
return S;
}
};
C++14 及以下版本
使用函数局部静态,因为它们更容易使用。
如果由于某种原因你真的希望有一个静态的数据成员,那么你可以使用模板技巧:
template <typename T = void>
struct Foo
{
static int I = 0; // inline initialization only for simple types.
};
template <typename T>
int Foo<T>::I;
关于本地静态
对于需要动态初始化的资源,最好使用本地静态。
通常,动态初始化文件范围或类范围静态的顺序是未定义的,当您尝试读取未初始化的静态作为另一个静态的初始化的一部分时,会导致静态初始化顺序失败。本地静态通过在首次使用时延迟初始化来解决该问题。
然而,使用本地静态数据会产生一些轻微的开销。从 C++11 开始,初始化需要是线程安全的,这通常意味着任何访问都由原子读取和良好预测的分支进行门控。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)