C++;静态成员变量范围 标题基本上说了这一切,我想知道C++类的静态成员何时被初始化,当它们超出范围时,

C++;静态成员变量范围 标题基本上说了这一切,我想知道C++类的静态成员何时被初始化,当它们超出范围时,,c++,scope,static-members,C++,Scope,Static Members,我需要这个来解决以下问题。我有一个类Foo的许多对象,每个对象都需要访问一个由另一个类栏封装的资源。同步不是问题,所以我希望所有对象共享同一个Bar实例 我使用一个简单的托管指针进行引用计数 我可以做到以下几点: class Foo { private: static managed_pointer<Bar> staticBar; public: Foo() { if(!staticBar) staticBar = new Ba

我需要这个来解决以下问题。我有一个类Foo的许多对象,每个对象都需要访问一个由另一个类栏封装的资源。同步不是问题,所以我希望所有对象共享同一个Bar实例

我使用一个简单的托管指针进行引用计数

我可以做到以下几点:

class Foo {
private:
    static managed_pointer<Bar> staticBar;
public:
    Foo() {
        if(!staticBar)
            staticBar = new Bar;
    }
    /*
     * use staticBar in various non-static member functions
     */
};

managed_pointer<Bar> Foo::staticBar = NULL;
class-Foo{
私人:
静态管理_指针静态条;
公众:
Foo(){
如果(!staticBar)
静态条=新条;
}
/*
*在各种非静态成员函数中使用staticBar
*/
};
托管指针Foo::staticBar=NULL;
托管指针staticBar应该在Bar对象超出范围后立即删除它-但是什么时候会发生这种情况?Foo的最后一个实例何时被销毁?申请退出时


谢谢你的建议

static
s和globals在程序启动之前初始化(在调用
main
之前,程序实际上在此之前启动),并在
main
退出后超出范围

异常-局部静态(在函数中声明的静态变量)和未使用的模板类
静态成员


它与实例的数量无关。

该标准没有指定精确的初始化顺序,它是特定于实现的。它们将在程序开始时实例化,并在程序结束时解除分配

你必须非常小心你在做什么,因为如果你有一些其他静态对象依赖于这个对象存在,它是UB。无法确定它们的初始化顺序

您可能会研究类似boost::call_once的内容,以确保它初始化一次,但我不会依赖于静态初始化的顺序

据我所知,您的代码可以工作,但我以前一直受到静态初始化问题的困扰,所以我想警告您


编辑:同样在您的代码中,当托管ptr超出范围(程序结束)时,它将自动删除分配的内存。但您不应该在Bar的析构函数中做任何非琐碎的事情,因为您可能会通过调用其他免费的实例或甚至已删除的代码来触发UB(就像我曾经在删除动态库时遇到的情况一样)。从本质上说,你处在一个雷区中,所以要小心。

从你的问题中冒出来的第一件事是一个常见的误解,即范围和寿命是等价的概念。事实并非如此。在某些情况下,与局部变量一样,生存期绑定到特定上下文,但情况并非总是如此


类静态成员变量具有类作用域(可在程序中的任何位置访问)和静态生存期,这意味着它将按照与同一翻译单元中的其他静态变量相关的顺序进行初始化,并按照与其他翻译单元中的其他静态变量相关的未定义顺序进行初始化,然后再进行主(注意:初始化不需要在main中的第一条语句之前执行,但保证在变量的第一次odr使用之前执行).

oops,感谢您修复了输入错误。当您删除最后一个实例或您的程序存在时,Foo的最后一个实例将被销毁。一个类的静态成员将存在,无论该类有多少个实例。本地静态变量在程序启动之前不会初始化。好的,谢谢。您的意思是什么“这与实例的数量无关"?类Foo的实例?是的,不管有多少个Foo实例,它们都将共享Bar。@Gabi或未使用的静态成员(如果类是模板)。@LeSnip3R:当然,这是我的意图,否则我可以将
Bar
设置为非静态成员,并让
Foo
的ctor和dtor负责分配/删除ing
Bar
。我不会在Foo中有任何其他的
static
s,但是谢谢你的警告,这是另一个值得记住的细节。编辑:也谢谢你的第二个警告,我会小心的。我的意思是,你的程序中有其他静态对象。如果以后你决定有另一个对象,比如说钢筋,那也是静态的,你会想吗“嘿,我可以调用Bar::Something,因为它是静态的”你应该小心。类静态成员变量有类作用域:它只在类中查找名称的上下文中可见。它有静态生存期和外部绑定(第三个概念,人们偶尔会把它与你提到的两个概念混淆)。不过,您已经提到了要点:生存期和作用域是正交的概念。(至少在某种程度上。在某些情况下,作用域决定生存期。)