Destruction order of static objects in C++

2019-01-04 01:55发布

Can I control the order static objects are being destructed? Is there any way to enforce my desired order? For example to specify in some way that I would like a certain object to be destroyed last, or at least after another static object?

9条回答
家丑人穷心不美
2楼-- · 2019-01-04 02:17

Do you really need the variable to be initialized before main?

If you don't you can use a simple idiom to actually control the order of construction and destruction with ease, see here:

#include <cassert>

class single {
    static single* instance;

public:
    static single& get_instance() {
        assert(instance != 0);
        return *instance;
    }

    single()
    // :  normal constructor here
    {
        assert(instance == 0);
        instance = this;
    }

    ~single() {
        // normal destructor here
        instance = 0;
    }
};
single* single::instance = 0;

int real_main(int argc, char** argv) {
    //real program here...

    //everywhere you need
    single::get_instance();
    return 0;
}

int main(int argc, char** argv) {
    single a;
    // other classes made with the same pattern
    // since they are auto variables the order of construction
    // and destruction is well defined.
    return real_main(argc, argv);
}

It does not STOP you to actually try to create a second instance of the class, but if you do the assertion will fail. In my experience it works fine.

查看更多
时光不老,我们不散
3楼-- · 2019-01-04 02:18

Static objects are destroyed in the reverse of the order in which they're constructed (e.g. the first-constructed object is destroyed last), and you can control the sequence in which static objects are constructed, by using the technique described in Item 47, "Ensure that global objects are initialized before they're used" in Meyers' book Effective C++.

For example to specify in some way that I would like a certain object to be destroyed last, or at least after another static onject?

Ensure that it's constructed before the other static object.

How can I control the construction order? not all of the statics are in the same dll.

I'll ignore (for simplicity) the fact that they're not in the same DLL.

My paraphrase of Meyers' item 47 (which is 4 pages long) is as follows. Assuming that you global is defined in a header file like this ...

//GlobalA.h
extern GlobalA globalA; //declare a global

... add some code to that include file like this ...

//GlobalA.h
extern GlobalA globalA; //declare a global
class InitA
{
  static int refCount;
public:
  InitA();
  ~InitA();
};
static InitA initA;

The effect of this will be that any file which includes GlobalA.h (for example, your GlobalB.cpp source file which defines your second global variable) will define a static instance of the InitA class, which will be constructed before anything else in that source file (e.g. before your second global variable).

This InitA class has a static reference counter. When the first InitA instance is constructed, which is now guaranteed to be before your GlobalB instance is constructed, the InitA constructor can do whatever it has to do to ensure that the globalA instance is initialized.

查看更多
登录 后发表回答