Search code examples
c++private-constructor

Why are the constructor Zlib_init kept private in class Zlib_init in the book by Bjarne Stroustrup


In the book The C++ Programming Language, by Bjarne Stroustrup, the author says:

Sometimes when you design a library, it is necessary, or simply convenient, to invent a type with a constructor and a destructor with the sole purpose of initialization and cleanup. Such a type would be used once only: to allocate a static object so that the constructor and the destructor are called. For example:

 class  Zlib_init
{
    Zlib_init() ; //get Zlib ready for use
   ~Zlib_init()  ; //clean up after Zlib
};
Class Zlib
{
   static  Zlib_init   x;
   /  /...
};

Unfortunately, it is not guaranteed that such an object is initialized before its first use and destroyed after its last use in a program consisting of separately compiled units.

Why does the author keep the constructor and destructor as private members? And why won't this method work if we use it in a program consisting of seperately compiled units? Won't it require definition of the member x for calling the constructor Zlib_init() and destructor ~Zlib_init()? Then what is the use of this method? It's in section 10.4.9 of the book.


Solution

  • Why does the author keep the constructor and destructor as private members?

    The constructor & destructor being private seems to be a typo.
    Class static members needs to be defined in order that you can use them. In order that the static member x is defined the constructor needs to be accessible. if not the linker will complain about undefined reference.

    Online Sample:

    class  Zlib_init 
    {    
       Zlib_init() ; //get Zlib ready for use  
      ~Zlib_init()  ; //clean up after Zlib 
       public:
         int j;
    };
    class Zlib 
    {  
       public:  
       static  Zlib_init   x;    
    }; 
    
    Zlib_init Zlib::x;
    
    int main()
    {
        Zlib::x.j = 10;
    
        return 0;
    }
    

    Output:

    prog.cpp:3: error: ‘Zlib_init::Zlib_init()’ is private     
    prog.cpp:14: error: within this context      
    prog.cpp: In static member function ‘static void Zlib::__static_initialization_and_destruction_0(int, int)’:     
    prog.cpp:4: error: ‘Zlib_init::~Zlib_init()’ is private     
    prog.cpp:14: error: within this context     
    

    And why won't this method work if we use it in a program consisting of seperately compiled units?

    If you fix the typo mentioned above by making the constructor and destructor public or by making Zlib a friend of class Zlib_init the code still faces another problem.
    The problem is popularly known as Static Initialization Fiasco in C++.

    Good Read:

    [10.14] What's the "static initialization order fiasco"?
    [10.17] How do I prevent the "static initialization order fiasco" for my static data members?