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?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
- What is the correct way to declare and use a FILE
The static objects are destructed in the reverse order of construction. And the order of construction is very hard to control. The only thing you can be sure of is that two objects defined in the same compilation unit will be constructed in the order of definition. Anything else is more or less random.
Short answer: In general, no.
Slightly longer answer: For global static objects in a single translation-unit the initialization order is top to bottom, the destruction order is exactly reverse. The order between several translation-units is undefined.
If you really need a specific order, you need to make this up yourself.
Theres no way to do it in standard C++ but if you have a good working knowledge of your specific compiler internals it can probably be achieved.
In Visual C++ the pointers to the static init functions are located in the
.CRT$XI
segment (for C type static init) or.CRT$XC
segment (for C++ type static init) The linker collects all declarations and merges them alphabetically. You can control the order in which static initialization occurs by declaring your objects in the proper segment usingfor example, if you want file A's objects to be created before file B's:
File A.cpp:
File B.cpp:
.CRT$XCB
gets merged in before.CRT$XCC
. When the CRT iterates through the static init function pointers it will encounter file A before file B.In Watcom the segment is XI and variations on #pragma initialize can control construction:
...see documentation for more
You can effectively achieve similar functionality by having a
static std::optional<T>
instead of aT
. Just initialize it as you'd do with a variable, use with indirection and destroy it by assigningstd::nullopt
(or, for boost,boost::none
).It's different from having a pointer in that it has preallocated memory, which is I guess what you want. Therefore, if you destroy it & (perhaps much later) recreate it, your object will have the same address (which you can keep) and you don't pay the cost of dynamic allocation/deallocation at that time.
Use
boost::optional<T>
if you don't havestd::
/std::experimental::
.No, you can't. You should never rely on the other of construction/destruction of static objects.
You can always use a singleton to control the order of construction/destruction of your global resources.
The other answers to this insist that it can't be done. And they're right, according to the spec -- but there is a trick that will let you do it.
Create only a single static variable, of a class or struct that contains all the other things you would normally make static variables, like so:
You can create the variables in whatever order you need to, and more importantly, destroy them in whatever order you need to, in the constructor and destructor for
StaticVariables
. To make this completely transparent, you can create static references to the variables too, like so:Voilà -- total control. :-) That said, this is extra work, and generally unnecessary. But when it is necessary, it's very useful to know about it.