C ++ 11中的静态局部变量?

时间:2016-01-19 06:10:01

标签: c++ c++11 static singleton

有什么区别:

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之间的Singleton的寿命是否存在差异?对象的内存位置?一般的差异是什么?

2 个答案:

答案 0 :(得分:8)

这两种情况下物体的寿命是不同的。 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分配的任何内容都将存储在堆中。

答案 1 :(得分:0)

添加第一个答案,2条评论(假设你想创建一个单例)。

  1. 如果2个线程尝试访问静态实例重叠,如果访问是第一次访问(运行构造函数时),则存在线程/竞争问题。如今,C ++具有编译器/标准支持,可以自动使这个静态单例初始化线程安全。
  2. 在堆情况下,您不希望每次都在堆上创建新实例。只需检查nullptr,并且只在第一次在堆上创建实例。
  3. 编辑:这是一个SO问题,答案中包含相关的标准参考:Heap/dynamic vs. static memory allocation for C++ singleton class instance