C++有用的基礎知識
阿新 • • 發佈:2022-03-06
C++有用的基礎知識合集。1.物件構造時執行的次序問題。2.待續
C++有用的基礎知識
基礎不牢,地動山搖
1.物件構造時執行的次序問題
- 一個類的例項化過程往往是發生瞭如下過程:
- 若存在基類,則基類先初始化。
- 若存在成員變數,則按照定義先後的順序初始化。
- 物件的析構順序則取之相反,是從外到內、從後到前發生。
- 如程式碼所示,定義了4個類,A、B、C、Base,其中C繼承自Base,A、B、Base基本只輸出基本構造、析構與賦值資訊,定義如下
檢視類A、B、Base的定義程式碼
class Base { public: Base() { cout << "base construct\n"; }; ~Base(){cout << "base destory\n";} }; class A { public: A() { cout << "A construct\n"; } A(const A &a) { cout << "A copy construct\n"; } ~A(){cout << "A destory\n";} void operator=(const A &a) { cout << "A assign function\n"; } }; class B { public: B() { cout << "B construct\n"; } B(const B &b) { cout << "B copy construct\n"; } ~B(){cout << "B destory\n";} void operator=(const B &b) { cout << "B assign function\n"; } };
class C : public Base
{
public:
B b;
A a;
C(){};
~C(){cout << "C destory\n";};
};
int main()
{
C c;
return 0;
}
執行結果:
base construct
B construct
A construct
C destory
A destory
B destory
base destory
- 在使用初始化列表時:
class C : public Base { private: B _b; A _a; public: C(A& a,B& b):_a(a),Base(){ _b=b; }; ~C(){cout << "C destory\n";}; }; int main() { A a; // 1 B b; // 2 C c(a,b); return 0; } 結果如下: --註釋掉的結果是 1 2 程式碼生成的 //A construct //B construct base construct B construct A copy construct B assign function C destory A destory B destory base destory //B destory //A destory
-
根據結果有幾點可以得出:
- 基類物件仍然是最先構建的。
- 初始化列表不能改變類成員初始化順序。C類中成員
_b
永遠在_a
前面。 - 在初始化列表中初始化的話,會呼叫複製建構函式。
- 在函式體中初始化會再次呼叫賦值函式,且是最後執行。
- 當需要對成員變數初始化特定值時,優先使用初始化列表方法。避免先初始化後再賦值的資源浪費行為。
-
從C++11開始,除 static 資料外,基本都允許在宣告處初始化成員變數。但有以下特例:
- 被常量表達式
constexpr
修飾的static可以在宣告處初始化。 - const static 整型可以宣告處初始化。整型有short、int、long等)。
- 被常量表達式
-
在C++11以前,除列舉型別和 const static 整型外,不可以宣告處初始化。
- const non-static型別必須用初始化列表語法初始化。
動手打一遍,才能記得住。 -- 魯迅