C++11 中的静态局部变量
Static local variable in C++11?
两者之间有什么区别:
class A {
public:
static const A& GetInstance() {
static A a;
return a;
}
};
和
class B {
public:
static const B* GetInstance() {
static B* b = new B;
return b;
}
};
?A 和 B 之间的单例寿命是否有区别?对象的内存位置?一般有什么区别吗?
在这两种情况下,对象的生存期是不同的。 C++保证静态局部对象将以与其构造相反的顺序销毁。 在这两种情况下,构造都将在首次调用GetInstance
时发生。
但是,在第二种情况下,变量b
被分配了一个分配有 new
的指针。 从静态存储中删除b
时,该内存将保留,直到堆最终被拆除。 在该阶段,它将被视为"泄漏",并且永远不会调用B
的析构函数(如果有)。
最好像这样实现基于指针的方法:
class B {
public:
static const B* GetInstance() {
static std::unique_ptr<B> b( new B );
return b.get();
}
};
现在,将调用B::~B()
(如果适用),并且在销毁内存时将正确删除该内存b
并且生存期与第一个示例相同。
这只留下了您关于内存位置的问题。 位置会有所不同。 静态变量通常存储在程序的数据段中,而分配new
的任何变量都将存储在堆中。
在第一个答案中添加 2 条注释(假设您要创建一个单例)。
- 如果 2 个线程尝试访问静态实例重叠,如果访问是第一次访问(运行构造函数时),则存在线程/争用问题。如今,C++具有编译器/标准支持,可自动使此静态单例初始化线程安全。
- 在堆情况下,您不希望每次都在堆上创建新实例。只需检查 nullptr,并且仅在第一次在堆上创建实例。
编辑:这是一个SO问题,其中答案包含与标准相关的参考:C++单例类实例的堆/动态与静态内存分配
相关文章:
- C++中静态方法的局部变量范围
- 获取具有静态局部变量的绑定/推断捕获 lambda 的函数指针
- 静态常量与常量局部变量,哪一个性能更好
- C++:用IIFE线程初始化静态局部变量安全吗
- 分配给静态变量的局部变量;编译错误在'c'但在 C++ 中成功
- 静态局部变量会被错误地优化吗?
- 为什么静态局部变量的 MSVC 线程安全初始化使用 TLS
- C++将局部变量添加到静态向量而不复制
- CppUnit:为什么静态局部变量保持其值
- 静态局部变量没有物理内存
- 静态对const局部变量有所作为
- 使用函数模板中静态局部变量的地址作为类型标识符是否安全
- 通过静态局部变量的参考/指针返回
- 递归计算在不使用静态局部变量,全局变量或静态函数的情况下,在递归函数中发生的环数
- 关于静态局部变量的澄清
- 如果在静态局部变量之前出现异常,会发生什么
- 其中定义函数的静态局部变量对象
- 在某些情况下,如何理解允许实现将非局部变量的动态初始化视为静态初始化
- C++ 中静态局部变量的范围和生存期
- 填充静态unordered_map局部变量