C++ static member class initialization details and instance code

  • 2020-05-17 05:56:00
  • OfStack

Class initialization details and instance code for C++ static members

1 generally speaking, the initialization of static members of C++ class is not difficult to understand, but when it comes to "in-class initialization" of C++ static members, it is easy to get confused.

Let's look at the following code:


//example.h
#include<iostream>
#include<vector>
using namespace std;

class Example{
public:
  static double rate = 6.5;
  static const int vecSize = 20;
  static vector<double> vec(vecSize);
};

//example.cpp
#include "example.h"
double Example::rate;
vector<double> Example::vec;

We need to determine if there are errors in the static data member declaration and definition above and explain why.

First, keep in mind that in general, members should not be initialized inside a class, whether static or not.

Second, if 1 must initialize a static member in a class, then the following conditions must be met:

1) the static member must be constexpr of literal constant type.

The so-called literal types are those commonly encountered: arithmetic types, references, Pointers, and so on. Literal constant types are const arithmetic types, references, Pointers, etc.

The so-called constexpr is a constant expression, which means that the value does not change and the result can be obtained during the compilation process. For example, literals, or const objects initialized with constant expressions are also constant expressions. To help users check whether the value of a variable they declare/define is a constant expression, C++11 allows variables to be declared of type constexpr so that the compiler can verify whether a variable is a constant expression.

2) the initial value provided to the static member must be a constant expression

Note: in version 5 of C++ primer, it is stated that only static members can be provided with an inclass initial value of the const integer type, and that the initial value of the const integer type must be a constant expression. I think it's wrong! See below for details.

With these two principles in place, we can validate the above code.

1) static double rate = 6.5;

Obviously it does not satisfy article 1: because rate is not a constant type. constexprt static const double rate = 6.5

It can also be seen from here that the initial value must be of type const integer.

ps: if we don't add the constexprt modifier here, the compiler will say: error: 'constexpr' needed for in-class data member' const double Example::rate' of non-integral type [-fpermissive]

Basically, for the initial value of a non-const integer type, if it is a constant expression, we need to manually add the modifier constexprt before it.

As for the definition section in the Example.cpp file, since we have already initialized it inside the class, we do not need to define it outside the class. If you want to define it, you must use the following format:


//example.cpp


constexpr const double Example::rate; // One of the const It can be deleted because constexprt It contains itself const

2) static const int vecSize = 20;

vecSize is of type const int and is a constant expression -- satisfies article 1; The initial value provided is 20, which is a constant expression -- satisfies clause 2! And since it is of type const int, the modifier constexpr can be omitted.

3) static vector < double > vec(vecSize);

Error! vector is a template not a literal constant type, so it does not meet article 1. It should be static vector < double > vec; // only and can only be declared, not defined

Then it is defined in Example.cpp:

static vector < double > vec(Example::vecSize);

Now we can add the test code to Example.cpp to test:


#include "example.h"
vector<double> Example::vec(Example::vecSize);
constexpr const double Example::rate;

int main(){

  Example::vec.push_back(10.5);
  cout << Example::vec.back() << endl;
  cout << Example::rate << endl;
  cout << Example::vecSize << endl;
}

Execution results:


wanchouchou@wanchouchou-virtual-machine:~/c++/7.5$ ./Example 
10.5
6.5
20

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: