Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的静态局部变量+;11?_C++_C++11_Static_Singleton - Fatal编程技术网

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

C++ C+中的静态局部变量+;11?,c++,c++11,static,singleton,C++,C++11,Static,Singleton,以下两者之间的区别是什么: class A { public: static const A& GetInstance() { static A a; return a; } }; 及 ??a和B之间的单子寿命有差异吗?对象的内存位置?一般来说有什么区别吗?在这两种情况下,对象的寿命是不同的。C++保证静态本地对象将按照其构造反向破坏。在这两种情况下,在第一次调用GetInstance时都会发生构造 然而,在第二种情况下,变量b被分配了一个指针,该指针

以下两者之间的区别是什么:

class A {
 public:
   static const A& GetInstance() {
     static A a;
     return a;
   }
};


??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*GetInstance(){
静态标准::唯一的ptr b(新b);
返回b.get();
}
};
现在,
B::~B()
将被调用(如果适用),当
B
被销毁时,该内存将被正确删除,其生存期与第一个示例相同


这就留下了关于内存位置的问题。地点会有所不同。静态变量通常存储在程序的数据段中,而使用
new
分配的任何内容都将存储在堆中。

在第一个答案中添加两条注释(假设您要创建一个单例)

  • 如果两个线程试图访问静态实例,并且访问是第一次访问(当构造函数运行时),则会出现线程/争用问题。现在,C++具有编译器/标准支持,自动地使这个静态单线程初始化线程安全。
  • 在堆的情况下,您不希望每次都在堆上创建一个新实例。只需检查nullptr,第一次只在堆上创建实例

  • 编辑:这里有一个SO问题,其中答案包含对标准的相关引用:

    事后考虑,当
    A
    B
    太大而无法分别放入堆或数据段时,程序行为也可能存在差异。如果
    B
    太大,那么
    new B
    应该抛出
    std::bad_alloc
    。在
    A
    的情况下,我不确定是否抛出了一个可捕获的异常,或者程序是否只会将故障隔离并终止。正如问题中提到的,在C++11中,(1)和(2)都是由编译器保证的。(1) 编译器保证静态局部变量初始化是线程安全的。(2) 编译器保证静态局部变量初始化只执行一次,并且对该函数的所有后续调用都将跳过静态局部变量的重新初始化(因此每次都不会创建新实例)。@iBrAaAa?问题未提及标准中的任何保证。相关章节为6.7.4,参见示例So,使用函数静态变量意味着您可以从标准中获得同步帮助。。
    class B {
      public:
       static const B* GetInstance() {
         static std::unique_ptr<B> b( new B );
         return b.get();
       }
    };