why the c++ constructor was not called when it appear as the static member variable?

余生颓废 提交于 2019-12-30 09:41:11

问题


I had a strange problem ,

declare a static member variable whose name is B class in A class . And initialize in the cpp file. but the constructor of B class was never called. I try to use some small test , the test constructor could be called normally. so it is very strange for our production system.

The code like this , in hpp:

class Test
{
    public:
    Test()
    {
        ofstream file("/tmp/wup.txt",ios::app);
        file << "wup in test" << endl;
        file.close();
    }
};

//## An extended personality
class TsdNAExtPersonality : public TsdNAPersonality{
public:

  TsdNAExtPersonality(
        s_gg62_personRec * gg62Header,
                   TsdNAFunctionType requiredFunctionType);
private:
  static Test test;

public:
  TsdNAExtPersonality( string * personalityFile, TsdNAFunctionType requiredFunctionType);
};

And in another cpp file I initialize with

Test TsdNAExtPersonality::test;

I have tried in several way, but i found all of ways are unusefull.

  1. did not set the variable as member variable but as global variable ==> also can't output
  2. change the member variable as pointer and change the initialize way as using new ==> no

the environment is HP-UX ,and the compile is aCC

so my question are :

  1. is there any compile option will influence the variable ? in other words, all the static variable will not be initialized.

  2. from the standard of C++ it should be called when the library was load, right?

  3. I put another static int value using the same way, it could be initialized. but the class constructor is not called , very strange.

  4. is there any mistake in my code ?


回答1:


from the standard of C++ it should be called when the library was load, right?

No. Dynamic initialisation of an object with static storage duration is guaranteed to happen before execution of any function defined in the same translation unit. If there are no such functions, or your program never calls them, then there's no guarantee that it will ever be initialised.

I put another static int value using the same way, it could be initialized. but the class constructor is not called , very strange.

An int variable is initialised statically, before the program starts, as long as its initialiser is constant.

is there any compile option will influence the variable ?

Not that I know of, but I'm not familiar with your platform. You could give yourself more control over the object's creation by scoping it within a function:

static Test & test() {
    static Test test;
    return test;
}

Now it is guaranteed to be initialised the first time the function is called. Of course, you'll need to remember to call it at some point.




回答2:


The startup and shutdown of a C++ program are sort of grey areas because it's not clear how much of your code you can already use (because it has been initialized) and how much is yet starting. At shutdown the same happens for destructor... it's not clear how many subsystems have been already shut down when your static instances are destroyed.

Moreover you should never use static initialization for anything that may fail, debugging before the start or after the end of main can be very difficult.

Note also that the order in which statics are initialized is not defined (except relative to other statics in the same compilation unit) and it may change from one compilation to the next. This means that you may live happy with a working program until for some strange reason you get a different initialization order and things stop working without any relevant change in the code.

Using static initialization for extremely simple things is ok, for anything else is not and you should do instead proper controlled initialization.




回答3:


I think there is a bug in your compiler.

Running this simple code on linux/g++ gives the expected results:

#include <iostream>

using namespace std;

class A
{
    public:
        A() { cout << "Hallo" << endl; }
};

class B
{
    public:
    static A a;
};

A B::a;    // < here the constructor must be called!

int main()
{
   cout << "Main runs" << endl;
   return 0;
}

Results in:

Hallo
Main runs

The constructor MUST be called when the static data member is constructed (commented line above).




回答4:


Static initialization in C++ is:

  • Zero initialization
  • Constant initialization
  • Dynamic initialization

Hence your best bet is initialization at first function call:

int fn() {
    static int result = 42;
    return result;
}

EDIT:

If you want to initialize before main:

struct Initialize { 
    Initialize() { fn(); }
}

Initialize initialize;


来源:https://stackoverflow.com/questions/18790849/why-the-c-constructor-was-not-called-when-it-appear-as-the-static-member-varia

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!