结论:
- 静态常量数据成员可以在类内初始化(即类内声明的同时初始化),也可以在类外,即类的实现文件中初始化,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化;
- 静态非常量数据成员只能在类外,即类的实现文件中初始化,也不能在构造函数中初始化,不能在构造函数的初始化列表中初始化;
- 非静态的常量数据成员不能在类内初始化,也不能在构造函数中初始化,而只能且必须在构造函数的初始化列表中初始化;
- 非静态的非常量数据成员不能在类内初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化;
总结如下表:
类型 初始化方式 |
类内(声明) |
类外(类实现文件) |
构造函数中 |
构造函数的初始化列表 |
非静态非常量数据成员 |
N |
N |
Y |
Y |
非静态常量数据成员 |
N |
N |
N |
Y (must) |
静态非常量数据成员 |
N |
Y (must) |
N |
N |
静态常量数据成员 |
Y |
Y |
N |
N |
以下三种类型必须通过初始化列表来初始化
1.非静态 常量
2. 引用类型
3. 没有默认构造函数的类类型
二.初始化顺序
-
继承的父类顺序,本类的类对象声明顺序,本类的基本类型声明顺序
#include<iostream> #include<pthread.h> #include<cstdlib> #include<cstring> using namespace std; class A{ public: int a; A(int i):a(i){ cout<<"A"<<endl; } }; class B{ public: int b; B(int i):b(i){ cout<<"B"<<endl; } }; class C{ public: int c; C(int i):c(i){ cout<<"C"<<endl; } }; class D{ public: int d; D(int i):d(i){ cout<<"D"<<endl; } }; class E:public B,public A{ public: E(int a,int b,int c,int d,int i):A(a),B(b),c1(c),d1(d),e(i){ cout<<"E"<<endl; } public: int e; D d1; C c1; }; int main() { E e(1,2,3,4,5); return 0; }
三.虚继承防止二义性
-
调用虚基类默认构造函数,然后派生类构造函数最后自己的构造函数
#include<iostream> #include<pthread.h> #include<cstdlib> #include<cstring> using namespace std; class A{ public: A():a(0){ cout<<"A():"<<this->a<<endl; }; A(int n):a(n){ cout<<"A(int n):"<<this->a<<endl; } private: int a; }; class B:virtual public A{ public: B(){ cout<<"B():"<<endl; } B(int n):A(n){ cout<<"B(int n):"<<endl; } }; class C:virtual public A{ public: C(){ cout<<"C():"<<endl; } C(int n):A(n){ cout<<"C(int n):"<<endl; } }; class D:public B,public C{ public: D():B(0),C(1){ cout<<"D():"<<endl; } D(int n):B(n),C(n+3){ cout<<"D(int n):"<<endl; } }; int main() { D d(4); return 0; }
链接:https://blog.csdn.net/sylar2016/article/details/79257175