Order of construction of static class members ? 
Author Message
 Order of construction of static class members ?

I have classes

class A
{
    long mydata;

    A() {mydata = 1;};

    long func() {return mydata;};

Quote:
}

class B
{
  static A myA;
  long myval;

  B () {myval = MyA.func();};        // Constructor calls static class
function

Quote:
}

and an defining reference elsewhere

A B::myA;

The constructor for the static member myA is not being called before the
constructor of B calls the function in myA (checked through breakpoints on
the constructor of A)

How do I get myA constructed before the rest of the B constructor executes ?

--

when reversed)



Tue, 27 Apr 2004 17:26:18 GMT  
 Order of construction of static class members ?
Hi, Jeremy,


Quote:
> I have classes

> class A
> {
>     long mydata;

>     A() {mydata = 1;};

>     long func() {return mydata;};
> }

> class B
> {
>   static A myA;
>   long myval;

>   B () {myval = MyA.func();};        // Constructor calls static class
> function
> }

> and an defining reference elsewhere

> A B::myA;

> The constructor for the static member myA is not being called before the
> constructor of B calls the function in myA (checked through breakpoints on
> the constructor of A)

> How do I get myA constructed before the rest of the B constructor executes
?

> --

net
> when reversed)

Try this code out and see the outut:

#include <iostream.h>
class A
{
public:
    long mydata;

    A() {
  cout<<"A constructor"<<endl;
  mydata = 1;
 }

    long func() {return mydata;};

Quote:
};

class B
{
public:
  static A myA;
  long myval;

  B () {
   myval = myA.func();
   cout<<"B constructor"<<endl;

Quote:
};

A B::myA;
int main(){
 B ob; /*and then comment out this declaration, run the prog agian and look
at
 the output, then you'll see then what's happening */
 return 0;

Quote:
}

Lucian


Tue, 27 Apr 2004 18:47:44 GMT  
 Order of construction of static class members ?
You haven't shown what causes B's constructor to be called in the first
place. If you have a global variable of type B in a module different from
the one where you declare B::myA, it is entirely possible to see the problem
you describe. The order of construction of global variables declared in
different modules is undefined.

You can solve it as follows:

class B
{
    static A& myA();
    long myval;
    B () { myval = myA().func();}

Quote:
};

A& B::myA()
{
    static A sA;
    return sA;

Quote:
}

Here sA is constructed the first time myA is called.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat, and
wrong." H.L. Mencken


Quote:
> I have classes

> class A
> {
>     long mydata;

>     A() {mydata = 1;};

>     long func() {return mydata;};
> }

> class B
> {
>   static A myA;
>   long myval;

>   B () {myval = MyA.func();};        // Constructor calls static class
> function
> }

> and an defining reference elsewhere

> A B::myA;

> The constructor for the static member myA is not being called before the
> constructor of B calls the function in myA (checked through breakpoints on
> the constructor of A)

> How do I get myA constructed before the rest of the B constructor executes
?

> --

net
> when reversed)



Wed, 28 Apr 2004 00:17:50 GMT  
 Order of construction of static class members ?

Quote:
> The order of construction of global variables
> declared in different modules is undefined.
> You can solve it as follows:

> class B
> {
>     static A& myA();
>     long myval;
>     B () { myval = myA().func();}
> };

> A& B::myA()
> {
>     static A sA;
>     return sA;
> }

Sorry, I forgot to mention that the instance of my class B was also static,
so your assumption is correct.

I will implement your solution.

It's a bit disappointing that the solution requires two function calls for
every actual call. This will impact on performance for all other functions
using the class. Is there no other way to determine the order of
construction of static class members?

Jeremy



Wed, 28 Apr 2004 08:22:19 GMT  
 Order of construction of static class members ?

Quote:
> It's a bit disappointing that the solution requires two function calls for
> every actual call. This will impact on performance for all other functions
> using the class. Is there no other way to determine the order of
> construction of static class members?

There is another way, but it is a bit tricky. Let's consider a simple case:

// A.h
class A
{
    int m; // needs initialization
public:
    A(int); // performs initialization

Quote:
};

extern A g_a;

// A.cpp
A g_a(5);

You want to make sure that g_a is constructed and usable from the
constructor of any other static object. The authors of STL face the same
problem with cin, cout and so on. Here is one possible solution, adapted
from Dinkumware STL:

// A.h
class A
{
public:
    A(int);
private:
    int m;
    class Init
    {
        static bool inited;
    public:
        Init();
    };
    enum no_init {NO_INIT};
    A(no_init) {} // does not perform any initialization by design

Quote:
};

extern A g_a;
static A::Init g_a_init;

// A.cpp
A g_a(A::NO_INIT);
bool A::Init::inited = false;
A::Init()
{
    if (!inited)
    {
        inited  = true;
        new (&g_a) A(5);
    }

Quote:
}

Here, every transation unit that includes A.h also creates an instance of
the object of type A::Init. Constructor of this object checks the static
flag and, if it is the first to be contructed, uses placement new operator
to explicitly invoke A's constructor.

This is probably not 100% standard-compliant. g_a is constucted twice - once
with a regular constuctor and once with a dummy no-op constructor, in
undefined order. For this to work, dummy constructor should indeed be no-op.
Not only should it be empty, but any base class and class data member of A
should also have such a dummy constructor invoked by this constructor.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat, and
wrong." H.L. Mencken



Fri, 30 Apr 2004 23:46:47 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. C++ static class members destruction order.

2. initialization order of static class member

3. Construction order of members/global objects

4. How can I control static object construction order?

5. Question about: FIX: Visual C++ Class Destructors Are Not Called in Reverse Order of Construction

6. Order of static member func execution before main()

7. does static class member change class size?

8. Class object as static member of another class

9. how to call a non-static member function of a class from a static member function of the class?

10. Class in Class construction

11. accessing static member of Windows service class thro reflection - need help

12. Initialising a static data member of a Class?

 

 
Powered by phpBB® Forum Software