C ++ Primer: within the class initialization static const data members and static constexpr of (7.58 Exercise answer)


1. Background

  In the Chinese version of C ++ Primer (5th Edition), page 270, the data members of the class static initialization described as follows:

We can provide an initial value within a class static const integer type of member, but requires a static member must be a literal constant type of constexpr.

  The above sentence is not well understood. So as to find the corresponding author Description:

we can provide in-class initializers for static members that have const integral type and must do so for static members that are constexprs of literal type.

  As English general meaning:

We can provide an initial value for the inner class static const int data member. Static member constexprs must be provided within the initial value of the class.

  Personal understanding:

  1. The arithmetic types, including integer and floating point. Integer including bool, char, int, short, long, etc. Including float float and double, etc. (see C ++ Primer, page 30).
  2. const int type of static data members (i.e., the static const int data members) may be initialized with the initial value of the class.
  3. constexprs static member (i.e., the static constexpr data members) must be provided with an initial value to initialize the class.

2. Examples

2.1 static data members

#include <iostream>
using namespace std;
class A
{
public:
    //整型的静态成员
    static bool b;
    static char c;
    static int i;
    //浮点型的数据成员
    static float f;
    static double d;

    // static int i1 = 1;       // 错误:带有类内初始值设定项的成员必须为常量
    // static double d1 = 3.14; // 错误:带有类内初始值设定项的成员必须为常量
};

bool A::b = true;
char A::c = 'a';
int A::i = 1;
float A::f = 1.5;
double A::d = 2.5;

int main()
{
    cout << A::b << endl;
    cout << A::c << endl;
    cout << A::i << endl;
    cout << A::f << endl;
    cout << A::d << endl;
    return 0;
}

operation result

to sum up:

  1. General static data members can only be declared in the class and outside the class definition and initialize.

2.2 static const data members

#include <iostream>
using namespace std;
class A
{
public:
    //整型的静态成员
    static const bool b1;
    static const char c1;
    static const int i1;
    //浮点型的数据成员
    static const float f1;
    static const double d1;

    //整型的静态成员
    static const bool b2 = false;
    static const char c2 = 'b';
    static const int i2 = 2;
    //浮点型的数据成员
    // static const float f2 = 3.5;  // 错误:"const float" 类型的成员不能包含类内初始值设定项
    // static const double d2 = 4.5; // 错误:"const double" 类型的成员不能包含类内初始值设定项

    // char m1[i1];// 错误:i1的常量还未初始化
    char m2[i2];
};

const bool A::b1 = true;
const char A::c1 = 'a';
const int A::i1 = 1;
const float A::f1 = 1.5;
const double A::d1 = 2.5;

const bool A::b2;
const char A::c2;
const int A::i2;

int main()
{
    cout << A::b1 << endl;
    cout << A::c1 << endl;
    cout << A::i1 << endl;
    cout << A::f1 << endl;
    cout << A::d1 << endl;
    cout << "---------------------------------------" << endl;
    cout << A::b2 << endl;
    cout << A::c2 << endl;
    cout << A::i2 << endl;
    return 0;
}

operation result

to sum up:

  1. static const data members can be declared within the class, and defined outside the class initialization. When you declare in the class, static const data members not yet initialized, not real const.
  2. static const int data members can be declared and initialized within the class, the class defined outside. When inside the class declaration and initialization, static const data members are truly const.
  3. If the available static const data members its compile-time value of the alternative (as indicated by the array number, etc.), it can be necessary to define. If not replaced (e.g., as parameters, etc.), it must contain a definition statement. Recommend whether or not alternative are defined outside the class once.
  4. If the data member is not static const int (bool, char, int, short , long , etc.) , the class is not initialized.

2.3 static constexpr data members

#include <iostream>
using namespace std;
class A
{
public:
    //整型的静态成员
    // static constexpr bool b1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
    // static constexpr char c1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
    // static constexpr int i1;  // 错误:constexpr 静态数据成员声明需要类内初始值设定项
    //浮点型的数据成员
    // static constexpr float f1;  // 错误:constexpr 静态数据成员声明需要类内初始值设定项
    // static constexpr double d1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项

    //整型的静态成员
    static constexpr bool b2 = false;
    static constexpr char c2 = 'b';
    static constexpr int i2 = 2;
    //浮点型的数据成员
    static constexpr float f2 = 3.5;
    static constexpr double d2 = 4.5;

    // char m1[i1]; // 错误:i1的常量还未初始化
    char m2[i2];
};

// constexpr bool A::b1 = true;
// constexpr char A::c1 = 'a';
// constexpr int A::i1 = 1;
// constexpr float A::f1 = 1.5;
// constexpr double A::d1 = 2.5;
constexpr bool A::b2;
constexpr char A::c2;
constexpr int A::i2;
constexpr float A::f2;
constexpr double A::d2;

int main()
{
    cout << A::b2 << endl;
    cout << A::c2 << endl;
    cout << A::i2 << endl;
    cout << A::f2 << endl;
    cout << A::d2 << endl;
    return 0;
}

operation result

to sum up:

  1. static constexpr data member must declare and initialize within the class. When inside the class declaration and initialization, static constexpr data member is truly const.
  2. If the data is available to members of its static constexpr compile-time value of the alternative (as indicated by the array number, etc.), it can be necessary to define. If not replaced (e.g., as parameters, etc.), it must contain a definition statement. Recommend whether or not alternative are defined outside the class once.
  3. If the static constexpr integer data member, if not, may be performed within the class initialization.

3. Problem resolved

Exercise 7.58: static data member of the following declarations and definitions have wrong? Please explain why.

#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);
};

double Example::rate;
vector<double> Example::vec;

answer:

  1. General static data members only within the class declaration, defined outside the class and initialization. rate is not static or static const constexpr, but generally static data members, the class is not initialized.
static double rate = 6.5;
//改为
static double rate;
  1. vecSize type is static const int, the class may be initialized. VecSize vector representing only the number of containers 20 can be directly used when compiling Alternatively, it is defined outside the class defined are possible or not, but preferably outside the class definition of a case.
static const int vecSize = 20; // 正确
// 最好在类外添加定义
static const int vecSize;
  1. vecSize initialized in class, it can be used to represent the capacity of the vector. vec just generally static data members, the class is not initialized.
static vector<double> vec(vecSize);
// 改为
// 类内
static vector<double> vec;
// 类外
vector<double> Example::vec(vecSize);

Modified:

#include <iostream>
#include <vector>
using namespace std;

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

double Example::rate;
static const int vecSize;
vector<double> Example::vec(vecSize);
Published 77 original articles · won praise 25 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_34801642/article/details/104948850