none
Where should v initialize static variables, header file or source file?

    Question

  • Should v initialize like this. .
    #ifndef parv_A
    #define parv_A
    
    namespace parv
    {
    	class A
    	{
    	public:
    		static int i;
    
    		A();
    	}
    
    	int A::i = 0;
    }
    
    #endif
    
    


    Or like this. .
    namespace parv
    {
    	A::A()
    	{
    	}
    
    	int A::i = 0;
    }
    


    Believes in simplicity, speed and stability.

    • Edited by Parv Tuesday, June 28, 2011 12:35 PM
    Tuesday, June 28, 2011 8:54 AM

Answers

  • Should v initialize like this. .

    Others have given good advice.  I will just elaborate (cause more confusion) on some terms.

    A static member variable is "declared" inside the class definition.  This is kind of like telling the compiler that there will be a static member variable that fits the following description.  e.g.

     

    class A
    {
      static int x; // declaration
    };
    
    A static member variable is "defined" outside the class definition. This tells the compiler to actually allocate an instance (memory) for the variable.

    int A::x; // definition
    
    The definition could be in the header, but others have given reasons why it is probably best to put the definition in the .cpp file.

    A third concept is "initialization".  This means, "When I create this variable, start off by giving it this value".  This is done by using the equal sign (or alternatively the constructor syntax (or initializer list)).  As others have shown, initialization is usually done with the static member variable's definition.

    int A::x = 3; // definition with an initialization
    
    However under certain circumstances it is legal to initialize a static member variable in its declaration.  These circumstances are approximetly that it be const and have an integral/enumeration data type.

     

    class A
    {
      static int const x = 3; // declaration with initialization, OK
    
      static int y = 4; // declaration with initialization, not OK because it is not const
    
      static float const z = 5.0; // declaration with initialization, not OK because it is not integral datatype
    
    };
    

     

    So now we have seen how you can initialize a static member variable (of const and integral type) in that member's declaration.  How does this effect that member's definition?  Well for starters, you would no longer provide an initialization in the static member definition:

    int const A::x; // if we initialize in the declaration, don't initialize in the definition
    
    Secondly, under restricted circumstances, you don't even need to provide a definition.  For instance, if you pass the variable by reference or take the address of it, you will still have to provide a definition.  Some compiler implementations might have taken the liberty to relax the restrictions.

     

    #include <iostream>
    
    class A
    {
     public:
      static int const x = 3;
    };
    
    // notice, no definition of x
    
    int main()
    {
      std::cout << x << std::endl; // OK, not taking address so its just treated like a compile time constant
      std::cout << &x << std::endl; // (probably) not OK, using address so we need an actual allocation
    }
    

     

    Finally in C++0x there is some potential that they will allow initialization of non-static member data in that member's declaration.  This means that that initializer will be used by default when an object is constructed.

     

    #include <iostream>
    
    class A
    {
     public:
      int y = 2;
    };
    
    int main()
    {
      A a;
      std::cout << a.y << std::endl; // prints 2
    }
    

     

    Unfortunately neither VS2010 nor any other compiler I have tried support non-static member initialization in declaration.
    • Marked as answer by Rob Pan Monday, July 04, 2011 2:07 AM
    Tuesday, June 28, 2011 5:22 PM
  • Parv wrote:

    Or like this. .

    namespace parv
    {
    A::A()
    {
    }
    
    int A::i = 0;
    }
    

    Like this. Declarations go into header file, definitions into cpp file.


    Igor Tandetnik

    • Proposed as answer by KarthikSr Tuesday, June 28, 2011 1:30 PM
    • Marked as answer by Rob Pan Monday, July 04, 2011 2:07 AM
    Tuesday, June 28, 2011 12:39 PM

All replies

  • You can initialize in cpp file.

    The sample taken from http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

    using namespace std;
    class CMyClass {
    public:
      static int m_i;
    };
    
    int CMyClass::m_i = 0;


    Thanks and Regards Selvam http://www15.brinkster.com/selvamselvam/
    Tuesday, June 28, 2011 9:11 AM
  • Parv wrote:

    Or like this. .

    namespace parv
    {
    A::A()
    {
    }
    
    int A::i = 0;
    }
    

    Like this. Declarations go into header file, definitions into cpp file.


    Igor Tandetnik

    • Proposed as answer by KarthikSr Tuesday, June 28, 2011 1:30 PM
    • Marked as answer by Rob Pan Monday, July 04, 2011 2:07 AM
    Tuesday, June 28, 2011 12:39 PM
  • The reason to have definitions in cpp:

    If you have definitions in header file and you use it across different files in the project. There will be multiple definition for same variable in each obj file that is compiled. This will result in linker error (multiple definitions). 

    Tuesday, June 28, 2011 1:20 PM
  • Should v initialize like this. .

    Others have given good advice.  I will just elaborate (cause more confusion) on some terms.

    A static member variable is "declared" inside the class definition.  This is kind of like telling the compiler that there will be a static member variable that fits the following description.  e.g.

     

    class A
    {
      static int x; // declaration
    };
    
    A static member variable is "defined" outside the class definition. This tells the compiler to actually allocate an instance (memory) for the variable.

    int A::x; // definition
    
    The definition could be in the header, but others have given reasons why it is probably best to put the definition in the .cpp file.

    A third concept is "initialization".  This means, "When I create this variable, start off by giving it this value".  This is done by using the equal sign (or alternatively the constructor syntax (or initializer list)).  As others have shown, initialization is usually done with the static member variable's definition.

    int A::x = 3; // definition with an initialization
    
    However under certain circumstances it is legal to initialize a static member variable in its declaration.  These circumstances are approximetly that it be const and have an integral/enumeration data type.

     

    class A
    {
      static int const x = 3; // declaration with initialization, OK
    
      static int y = 4; // declaration with initialization, not OK because it is not const
    
      static float const z = 5.0; // declaration with initialization, not OK because it is not integral datatype
    
    };
    

     

    So now we have seen how you can initialize a static member variable (of const and integral type) in that member's declaration.  How does this effect that member's definition?  Well for starters, you would no longer provide an initialization in the static member definition:

    int const A::x; // if we initialize in the declaration, don't initialize in the definition
    
    Secondly, under restricted circumstances, you don't even need to provide a definition.  For instance, if you pass the variable by reference or take the address of it, you will still have to provide a definition.  Some compiler implementations might have taken the liberty to relax the restrictions.

     

    #include <iostream>
    
    class A
    {
     public:
      static int const x = 3;
    };
    
    // notice, no definition of x
    
    int main()
    {
      std::cout << x << std::endl; // OK, not taking address so its just treated like a compile time constant
      std::cout << &x << std::endl; // (probably) not OK, using address so we need an actual allocation
    }
    

     

    Finally in C++0x there is some potential that they will allow initialization of non-static member data in that member's declaration.  This means that that initializer will be used by default when an object is constructed.

     

    #include <iostream>
    
    class A
    {
     public:
      int y = 2;
    };
    
    int main()
    {
      A a;
      std::cout << a.y << std::endl; // prints 2
    }
    

     

    Unfortunately neither VS2010 nor any other compiler I have tried support non-static member initialization in declaration.
    • Marked as answer by Rob Pan Monday, July 04, 2011 2:07 AM
    Tuesday, June 28, 2011 5:22 PM