简体   繁体   中英

c++ When does the constructor for a statically allocated object run

Consider a class Cow that has an overload constructor Cow:Cow (int i);

Now I Statically allocate Cow myCow(4);

Exactly when is this non default constructor run? Is this a good practice or are there any gotchas?

It depends on the scope of the static.

At file scope the static variable is initialised at some point before main() is called. The order of initialisation is not defined, so you must not rely on it. Note that static members of classes are at file scope for the purposes of initialisation timing.

eg

static X global_x; // initialised before main() is called

If the static variable is defined at function scope, it is initialised the first time the program flows over it. Yes, this means that if the function is never called, it is never initialised. Again, for our purposes, functions, methods and static methods are treated equivalently.

eg

X& func()
{
  static X my_x;  // initialised the first time the program counter gets here
  return my_x;
}

appendix for further understanding:

  1. File-scope statics in the same translation unit are initialised in top-town order, so their initialisation order is predictable relative to each other. Order cannot be predicted between translation units.

  2. Destruction of static objects takes place strictly in reverse order of construction, whatever that may have been. This gives a degree of predictability and means that (for example) a function-scope static may depend on the lifetime of another function-scope static or a file-scope static... provided the function-scope static was not initialised by another file-scope static in a different translation unit :-)

demo:

Here's a little demo to illustrate initialisation and de-initialisation order. Note that the function make_fox() is called before main() . Care is required.

#include <iostream>

using namespace std;

struct chicken
{
    chicken() { std::cout << "chicken" << std::endl; }
    ~chicken() { std::cout << "~chicken" << std::endl; }

};

chicken licken;

class fox;
fox& make_fox();

struct eagle
{
    eagle() { std::cout << "eagle" << std::endl; }
    ~eagle() { std::cout << "~eagle" << std::endl; }

    fox& _fox = make_fox();
};

class fox
{
    fox() { std::cout << "fox" << std::endl; }
    ~fox() { std::cout << "~fox" << std::endl; }

    friend fox& make_fox();

    chicken& _chicken = licken;
};

eagle eagle1;

fox& make_fox()
{
    static fox _fox;
    return _fox;
}


auto main() -> int
{
    cout << "Hello, World" << endl;
    return 0;
}

expected output:

chicken
fox
eagle
Hello, World
~eagle
~fox
~chicken

Your answer can be found in articles about the static initialization order fiasco (eg this one ).

For a global variable, initialization (call of constructor) happens before main() starts. If you have multiple global variables in the same compilation unit (.cpp), initialization happens in top-down order. If you have multiple global variables in multiple compilation units (.cpp), the initialization order is unspecified (random).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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