結論:
- 靜態常量數據成員可以在類內初始化(即類內聲明的同時初始化),也可以在類外,即類的實現文件中初始化,不能在構造函數中初始化,也不能在構造函數的初始化列表中初始化;
- 靜態非常量數據成員只能在類外,即類的實現文件中初始化,也不能在構造函數中初始化,不能在構造函數的初始化列表中初始化;
- 非靜態的常量數據成員不能在類內初始化,也不能在構造函數中初始化,而只能且必須在構造函數的初始化列表中初始化;
- 非靜態的非常量數據成員不能在類內初始化,可以在構造函數中初始化,也可以在構造函數的初始化列表中初始化;
總結如下表:
類型 初始化方式 |
類內(聲明) |
類外(類實現文件) |
構造函數中 |
構造函數的初始化列表 |
非靜態非常量數據成員 |
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