主要的差別在於初始化的時機不同。
另外一個差別是,使用initializer list初始化成員變數需要在每個constructor中都需要手動初始化,而直接賦值的方式只需要在類別定義時指定一次即可。
補充:
Test2 類別中的 x、y、z 成員變數在類別定義時就已經被初始化為 10 了。
當你建立 Test2 的物件時,不需要再次初始化 x、y、z 成員變數,因為它們已經在類別定義時被初始化過了。
而 Test1 情況下,每個成員變數在建構子建立類別物件時,才會被初始化和賦值。
弱弱問一句,原來可以這樣操作嗎?
#include <iostream>
class Test1 {
public:
int x;
int &y;
const int z;
Test1():
x(10),
y(x), // <-- 原來可以這樣操作嗎?
z(10)
{}
};
class Test2 {
public:
int x = 10;
int &y = x;
const int z = 10;
};
int main() {
Test1 test1;
std::cout << test1.y << std::endl;
return 0;
}
不太理解您第二點說的:
"Test2成員變數的初始化和賦值是在類別定義時進行"
非靜態的成員變數不是都應該在建立物件時才初始化和賦值嗎?
而類別定義應是載入時會預先分配記憶體(您的意思是Test2的物件在此時還未建立就會進行初始化和賦值嗎?)
還是我誤解了什麼? (抱歉,我不太了解c++底層的運作XD)
(t2是在物件建立時才初始化和賦值)
造成你的誤會,已更新補充
感謝,我大致理解了。
另外再請問一下,為什麼像是Test2這樣的寫法較少看到有人使用呢?(如果是在建立物件時不需傳入初值的情況下)使用constructor會比直接賦值多出什麼好處?
如果成員變數需要一些特殊的初始化過程,比如計算初始值或者某些其他邏輯,則不能使用Test2這種方式初始化
舉例來說,假設有一個類別叫做 "String",裡面有一個成員變數 "str",用來儲存字串。如果想要在建立物件時將str初始化為某個字串的反轉版本,那麼就不能使用Test2這種方式初始化。因為在類別定義時無法執行反轉字串的邏輯.
假設您有一個類別叫做 "BankAccount",它有一個成員變數 "balance",並且您需要在建立物件時檢查賬戶餘額是否足夠,如果不足則賦值為0。在這種情況下,您不能使用Test2的寫法,因為您需要在建立物件時檢查餘額並賦值。
所以通常都使用constructor來初始化成員變數。
了解,謝謝!