简体   繁体   English

C ++静态成员变量范围

[英]C++ static member variable scope

The title basically says it all, i wonder when static members of a c++ class are initialized and when they go out of scope. 标题基本上都说明了这一点,我想知道什么时候初始化c ++类的静态成员以及它们何时超出范围。

I need this for the following problem. 我需要这个以解决以下问题。 I have many objects of a class Foo and each object needs access to a resource, encapsulated by another class Bar. 我有很多Foo类的对象,每个对象都需要访问一个资源,由另一个类Bar封装。 Synchronization is not an issue, so i want all objects to share the same Bar instance. 同步不是问题,所以我希望所有对象共享相同的Bar实例。

I'm using a simple managed pointer for reference counting. 我正在使用一个简单的托管指针进行引用计数。

Can i do the following: 我可以做以下事情:

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;

the managed_pointer staticBar should delete the Bar object as soon as it goes out of scope - but when does this happen? managed_pointer staticBar应该在它超出范围时立即删除它 - 但是什么时候会发生? when the last instance of Foo is destructed? 当Foo的最后一个实例被破坏时? on application exit? 在申请退出?

Thanks for your advice! 谢谢你的建议!

static s and globals are initialized right before the program starts (before main is called, the program actually starts before that) and go out of scope after main exits. static s和globals在程序启动之前初始化(在调用main之前,程序实际上在此之前启动)并在main退出之后超出范围。

Exceptions - local statics (static variables declared inside functions) and unused template class static members. 异常 - 本地静态(函数内部声明的静态变量)和未使用的模板类static成员。

It has nothing to do with the number of instances. 它与实例数无关。

The standard does not specify a precise order of initialization, it is implementation specific. 该标准没有指定初始化的精确顺序,它是特定于实现的。 They will be instantiated at the start of the program and deallocated at the end. 它们将在程序开始时实例化,并在最后解除分配。

You have to be very careful with what you are doing, because if you have some other static objects that rely on this object to exist, it's UB. 你必须非常小心你正在做的事情,因为如果你有一些其他依赖这个对象存在的静态对象,它就是UB。 There is no telling in what order they will be initialized. 没有人知道他们将以什么顺序进行初始化。

You could possibly look into something like boost::call_once to ensure it's initialized once, but I wouldn't rely on the order the statics are initialized. 您可以查看boost :: call_once之类的内容以确保它初始化一次,但我不会依赖于初始化静态的顺序。

For all I know, you code would work, but I've been bitten by the static initialization issue before so I wanted to warn you. 据我所知,你的代码可以工作,但我之前被静态初始化问题所困扰所以我想警告你。

EDIT: Also in your code, when the managed_ptr will go out of scope (end of program), it will delete the memory allocated automatically. 编辑:同样在您的代码中,当managed_ptr超出范围(程序结束)时,它将删除自动分配的内存。 But you should not do anything non-trivial in Bar's destructor as you may trigger UB by calling into other free'd instances or even code that has been removed (as it happened to me once where a dynamic library had been removed). 但是你不应该在Bar的析构函数中做任何不重要的事情,因为你可以通过调用其他free'd实例甚至是已经被删除的代码来触发UB(因为它发生在我曾经删除动态库的地方)。 Essentially you are in a minefield, so watch out. 基本上你是在一个雷区,所以要小心。

The first thing that pops out of your question is the common misconception that scope and lifetime are equivalent concepts. 从您的问题中突然出现的第一件事是常见的误解,即范围生命周期是等同的概念。 They are not. 他们不是。 In some cases as with local variables, the lifetime is bound to a particular context , but that is not always the case. 在某些情况下,与局部变量一样, 生命周期与特定上下文绑定,但情况并非总是如此。

A class static member variable has class scope (it is accessible anywhere in the program) and static lifetime , which means that it will be initialized in order with respect to the other static variables in the same translation unit, and in an undefined order with respect to other static variables in other translation units, before main (caveat: initialization need not be performed before the first statement in main, but it is guaranteed to be before the first odr-use of the variable). 类静态成员变量具有类作用域 (可在程序中的任何位置访问)和静态生存期 ,这意味着它将按照相同转换单元中的其他静态变量的顺序进行初始化,并且以未定义的顺序进行初始化 main 之前的其他翻译单元中的其他静态变量(警告:初始化不需要在main中的第一个语句之前执行,但保证在变量的第一次使用之前)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM