C++11 快速初始化成员变量

【1】“就地”声明

C++98中,支持在类声明的时候使用等号"="初始化类中静态成员变量,这种声明方式我们称之为“就地”声明。

但是,C++98要求静态成员必须满足常量性,而且类型必须是整型或者枚举型,而非静态成员变量的初始化则必须在构造函数中进行。

如下示例:

 1 class Init 
 2 {
 3 public:
 4     Init() : a(0)
 5     {}
 6     Init(int d) : a(d) 
 7     {}
 8 private:
 9     int a;
10     const static int b = 0;
11     int c = 1;                         //成员,无法通过编译
12     static int d = 0;                  //成员,无法通过编译
13     static const double e = 1.3;       //非整型或者枚举型,无法通过编译
14     static const char* const f = "e";  //非整型或者枚举型,无法通过编译
15 };

如上各种情况均无法通过编译。

【2】C++11中的区别

C++11中,允许使用 等号= 或者 花括号{} 进行就地的非静态成员变量初始化。如下示例:

 1 struct C 
 2 {
 3     C(int i, int j) :c(i), d(j)
 4     {};
 5 
 6     int c;
 7     int d;
 8 };
 9 
10 struct init
11 {
12     int a = 1;
13     string b{ "hello" };
14     C c{ 1, 3 };
15 };

从第12、13、14行可以看到,使用等号或花括号进行就地初始化。

如此使用后的注意事项

[1] 初始化列表的效果总是优先于就地初始化。如下示例:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 struct Test
 5 {
 6     Test() {};
 7     Test(int i) : c(i)
 8     {};
 9 
10     int c = 2;
11 };
12 
13 int main() 
14 {
15     Test c1;
16     Test c2(500);
17 
18     cout << c1.c << endl;   // 2
19     cout << c2.c << endl;   // 500
20 }

[2] 对于非常量的静态成员变量,C++11与C++98保持一致:

仍然还是要在头文件以外的位置定义它,这会保证编译时,类静态成员的定义最后只存在于一个目标文件中。

如下示例:

 1 // 正确情况:
 2 struct S
 3 {
 4     S() {};
 5     S(int i) : s(i) {};
 6 
 7     int s = 2;
 8     static int p;
 9 };
10 
11 int S::p = 3;
12 
13 // 错误情况:
14 struct C
15 {
16     C() {};
17     C(int i) : c(i) {};
18 
19     int c = 2;
20     static int d = 3;  //报错 Non-const static data member must be initialized out of line
21 };

[3] 相对于传统的初始化列表,在类声明中对非静态成员变量进行就地列表初始化可以降低程序员的工作量。

当然,我们只在有多个构造函数,且有多个多个成员变量的时候可以看到新方式带来的便利。如下示例:

 1 #include <string> 
 2 using namespace std; 
 3 
 4 class Mem 
 5 { 
 6 public: 
 7     Mem(int i) : m(i)
 8     {}
 9 
10  private: 
11     int m; 
12 };
13 
14 class Group 
15 { 
16 public: 
17     Group() {}                // 这里就不需要初始化data、mem、name成员了 
18     Group(int a) : data(a) {} // 这里就不需要初始化mem、name成员了
19     Group(Mem m) : mem(m) {}  // 这里就不需要初始化data、name成员了 
20     Group(int a, Mem m, string n) : data(a), mem(m), name(n)
21     {}
22 
23 private: 
24     int data = 1; 
25     Mem mem{0}; 
26     string name{" Group"}; 
27 };

 

good good study, day day up.

顺序 选择 循环 总结

posted @ 2020-01-22 00:49  kaizenly  阅读(6598)  评论(0编辑  收藏  举报
打赏