Analysis of Member Variables in C++ with static or const Keyword

Initialization of class member variables in C++ with static or const keywords. Define the following variables in a simple C++ class:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable(){}  
  8.     private:  
  9.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  10.     const int constIntVariable;//Case 1: const constant  
  11.     static int staticIntVariable;//Case 2: Static variables  
  12.     static const int staticConstIntVariable;//Case 3 Static constant type  
  13.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  14. };  
  15.   
  16. int main(){  
  17.     TestVariable variable;  
  18.     return 0;  
  19.   
  20. }  
After adding the qualifier, there are four more cases. The following four cases are analyzed separately.

Case 1: const Modification

Compiling the above code, first of all, there is a problem in case 1. The error hint in g++ is:


The prompt in vs is more obvious, "error C2758:" TestVariable::constIntVariable": must be initialized in the list of constructor base/member initializers. The solution is given directly, that is to say, for const constant types in classes, initialization needs to be done in the constructor initialization list.

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6. public:  
  7.     TestVariable()<span style="color:#ff0000;">:constIntVariable(0)</span>{}  
  8. private:  
  9.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  10.     const int constIntVariable;//Case 1: const constant  
  11.     static int staticIntVariable;//Case 2: Static variables  
  12.     static const int staticConstIntVariable;//Case 3 Static constant type  
  13.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  14. };  
  15.   
  16. int main(){  
  17.     TestVariable variable;  
  18.     return 0;  
  19.   
  20. }  
In this way, the problem of case 1 is solved.

Situation 2: static Modification

Then compile the above code to pass, but obviously there is a problem that the static variable is not initialized, but there is no error in compiling. The reason is that these variables have not been used yet, because the static variables are shared by all instances of the class, so constIntVariable is only checked when the variable is constructed. The compilation error occurs, but the remaining three static variables do not see the problem because they are not used all. Modify the code to check for static variables in case 2:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     <span style="color:#ff0000;">void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }</span>  
  12.     private:  
  13.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  14.     const int constIntVariable;//Case 1: const constant  
  15.     static int staticIntVariable;//Case 2: Static variables  
  16.     static const int staticConstIntVariable;//Case 3 Static constant type  
  17.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  18. };  
  19.   
  20. int main(){  
  21.     TestVariable variable;  
  22.     variable.printStaticInt();  
  23.     return 0;  
  24.   
  25. }  
Errors in g++ compilation are as follows:



The error prompt in GS is "error LNK2001: the external symbol"private: static int Test Variable:: static IntVariable"(? Static IntVariable@TestVariable@@0HA). In this case, the prompt in g++ is more obvious, that is, an undefined reference to the variable TestVariable:: static IntVariable, so our solution is to initialize it. Initialization of this variable operates as follows:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.     private:  
  13.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  14.     const int constIntVariable;//Case 1: const constant  
  15.     static int staticIntVariable;//Case 2: Static variables  
  16.     static const int staticConstIntVariable;//Case 3 Static constant type  
  17.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  18. };  
  19. <span style="color:#ff0000;">int TestVariable::staticIntVariable=1;</span>  
  20. int main(){  
  21.     TestVariable variable;  
  22.     variable.printStaticInt();  
  23.     return 0;  
  24.   
  25. }  

Note that int TestVariable::staticIntVariable=1; this line of code cannot be written as static int TestVariable::staticIntVariable=1; otherwise this error will occur in g++:


In vs, the error C2720: "TestVariable::staticIntVariable": the "static" storage class descriptor on the member is illegal is an error prompt.

Case 3: static const modified integer data

Then there's case 3 and case 4, where the qualifier is the same as case 3 and case 4, which is static const (written here as static const and const static seems to work, at least in vs and g++). test All pass, but the difference is the data type, where int type is a special case, that is, static constant integer (short). Int, long, long) data can be initialized in a class, while other types can only be initialized outside the class.

First, add a function that calls this variable:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.   
  13.     <span style="color:#ff0000;">void printStaticConstInt(){  
  14.         cout<<"staticOnstIntVariable:"<<staticConstIntVariable<<endl;  
  15.     }</span>  
  16.     private:  
  17.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  18.     const int constIntVariable;//Case 1: const constant  
  19.     static int staticIntVariable;//Case 2: Static variables  
  20.     static const int staticConstIntVariable;//Case 3 Static constant type  
  21.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  22. };  
  23.  int TestVariable::staticIntVariable=1;  
  24. int main(){  
  25.     TestVariable variable;  
  26.     variable.printStaticInt();  
  27.     variable.printStaticConstInt();  
  28.     return 0;  
  29.   
  30. }  

The result of compiling in g++ is as follows:

Error compiled with vs: "error LNK2001: The unresolved external symbol"private: static int const TestVariable:: static Const IntVariable"(? Static Const IntVariable@TestVariable@@0HB)) is the same as the error prompt in case 2.

There are only two ways to define it, in the class definition:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.   
  13.     void printStaticConstInt(){  
  14.         cout<<"staticOnstIntVariable:"<<staticConstIntVariable<<endl;  
  15.     }  
  16.     private:  
  17.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  18.     const int constIntVariable;//Case 1: const constant  
  19.     static int staticIntVariable;//Case 2: Static variables  
  20.     <span style="color:#ff0000;">static const int staticConstIntVariable=3;//Case 3 Static constant type</span>  
  21.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  22. };  
  23.  int TestVariable::staticIntVariable=1;  
  24. int main(){  
  25.     TestVariable variable;  
  26.     variable.printStaticInt();  
  27.     variable.printStaticConstInt();  
  28.     return 0;  
  29.   
  30. }  
Define outside the class:
  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.   
  13.     void printStaticConstInt(){  
  14.         cout<<"staticOnstIntVariable:"<<staticConstIntVariable<<endl;  
  15.     }  
  16.     private:  
  17.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  18.     const int constIntVariable;//Case 1: const constant  
  19.     static int staticIntVariable;//Case 2: Static variables  
  20.     static const int staticConstIntVariable;//Case 3 Static constant type  
  21.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  22. };  
  23.  int TestVariable::staticIntVariable=1;  
  24. <span style="color:#ff0000;"const int TestVariable::staticConstIntVariable=3;</span>  
  25. int main(){  
  26.     TestVariable variable;  
  27.     variable.printStaticInt();  
  28.     variable.printStaticConstInt();  
  29.     return 0;  
  30.   
  31. }  
Note that the keyword const is also needed here, otherwise there will be an error in g++: it will treat it as a new variable, but the variable name is the same as that of the original const type, so it will make a mistake.



The prompt in vs is "error C2373:" static Const Int Variable: redefinition; different type modifiers".

Case 4: static const modified non-integer data

Then case 4, for static constant non-integer data, if initialization is done within the class:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6.     public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.   
  13.     void printStaticConstInt(){  
  14.         cout<<"staticOnstIntVariable:"<<staticConstIntVariable<<endl;  
  15.     }  
  16.     void printStaticConstNotIntVariable(){  
  17.         cout<<"staticConstNotIntVariable:"<<staticConstNotIntVariable<<endl;  
  18.     }  
  19.     private:  
  20.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  21.     const int constIntVariable;//Case 1: const constant  
  22.     static int staticIntVariable;//Case 2: Static variables  
  23.     static const int staticConstIntVariable;//Case 3 Static constant type  
  24.     <span style="color:#ff0000;">static const float staticConstNotIntVariable=4.0;//Case 4: Static very integer type</span>  
  25. };  
  26.  int TestVariable::staticIntVariable=1;  
  27.  const int TestVariable::staticConstIntVariable=3;  
  28. int main(){  
  29.     TestVariable variable;  
  30.     variable.printStaticInt();  
  31.     variable.printStaticConstInt();  
  32.     variable.printStaticNotIntVariable();  
  33.     return 0;  
  34.   
  35. }  
No problem in g++:

This error "error C2864:" TestVariable:: static ConstNotIntVariable"will appear in vs 2008: Only static constant integer data members can be initialized in the class.

So it's better not to write this code.

Putting the initialization of variables outside the class is as good as case 3.

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. class TestVariable{  
  6. public:  
  7.     TestVariable():constIntVariable(0){}  
  8.   
  9.     void printStaticInt(){  
  10.         cout<<"staticIntVariable:"<<staticIntVariable<<endl;  
  11.     }  
  12.   
  13.     void printStaticConstInt(){  
  14.         cout<<"staticOnstIntVariable:"<<staticConstIntVariable<<endl;  
  15.     }  
  16.     void printStaticConstNotIntVariable(){  
  17.         cout<<"staticConstNotIntVariable:"<<staticConstNotIntVariable<<endl;  
  18.     }  
  19. private:  
  20.     int intVariable;//Case 0: No qualifier, this need not be discussed  
  21.     const int constIntVariable;//Case 1: const constant  
  22.     static int staticIntVariable;//Case 2: Static variables  
  23.     static const int staticConstIntVariable;//Case 3 Static constant type  
  24.     static const float staticConstNotIntVariable;//Case 4: Static very integer type  
  25. };  
  26. int TestVariable::staticIntVariable=1;  
  27. const int TestVariable::staticConstIntVariable=3;  
  28. <span style="color:#ff0000;">const float TestVariable::staticConstNotIntVariable=4.0;</span>  
  29. int main(){  
  30.     TestVariable variable;  
  31.     variable.printStaticInt();  
  32.     variable.printStaticConstInt();  
  33.     variable.printStaticConstNotIntVariable();  
  34.     return 0;  
  35.   
  36. }  

This is the case in g++ and vs run the results are correct.


Finally, with regard to static, it has different meanings in and out of classes. Here's a summary:

1. The static variable in the function body acts as the function body. Unlike the auto variable, the memory of the variable can only be allocated once, so its value remains the last value when it is called next time.

2. static global variables within a module can be accessed by all functions within the module, but not by other functions outside the module.

3. static functions within a module can only be called by other functions within the module, and the scope of use of this function is limited to the module that declares it.

4. static member variables in a class belong to the whole class, and only one copy of all objects in the class.

5. The static member function in the class belongs to the whole class. This function does not accept this pointer, so it can only access the static member variable of the class.

Posted by swampone on Mon, 17 Jun 2019 17:39:36 -0700