Question

I understand that the code below would result segmentation fault because at the cstr of A, B::SYMBOL was not initialized yet. But why?

In reality, A is an object that serves as a map that maps the SYMBOLs of classes like B to their respective IDs. C holds this map(A) static-ly such that it can provide the mapping as a class function.

The primary function of A is to serve as a map for C that initializes itself at startup. How should I be able to do that without segmentation fault, provided that I can still use B::ID and B::SYMBOL in the code (no #define pls)?

(ps. assume I have implemented the include guards)

//A.h
    #include "B.h"
    class A
    {
    public:
      A()
      {
        std::cout<<B::ID<<std::endl;
        std::cout<<B::SYMBOL<<std::endl;
      }
    };

//B.h    
    class B
    {
    public:
      static const int ID;
      static const std::string SYMBOL;
    }

//B.cpp    
    #include "B.h"
    const int B::ID = 1;
    const std::string B::SYMBOL = "B";

//C.h    
    #include "A.h"
    class C
    {
    public:
      static A s_A;
    };

//C.cpp    
    #include "C.h"
    A C::s_A;

//main.cpp    
    #include "C.h"
    int main(int c, char** p)
    {
    }
Was it helpful?

Solution

Use lazy initialization of s_A. This might work:

class C
{
public:
  static A& getA() { static A s_A; return s_A; }
};

Or:

class C
{
public:
  static A& getA() 
  { 
    if( ps_A == NULL) ps_A = new ps_A; 
    return *ps_A; 
  }
private:
  static A* ps_A;
};

A* C::ps_A = NULL;

Neither solution is thread safe.

OTHER TIPS

What segmentation fault are you talking about? Your code simply will not compile, because members of B (and B itself) are not declared before A::A(). The compiler simply will not know what B is.

If you exchange the definitions of A and B, then the code should compile and work fine. As as long as everything is in the same translation unit, there shouldn't be any problems with the initialization order, assuming that the definitions of static members of B precede the definition of C::s_A. Objects defined in the same translation unit are initialized in the order of their definition, meaning that by the time A::A() starts, static members of B are already initialized. There's no potential for the segmentation fault in this case as presented.

If you are getting a segmentation fault, you must be doing something differently. Order of definition is different? Multiple translation units maybe? Post/describe the real code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top