委派建構函式
許多類別都有多個建構函式來執行類似的事情,例如,驗證參數:
class class_c {
public:
int max;
int min;
int middle;
class_c() {}
class_c(int my_max) {
max = my_max > 0 ? my_max : 10;
}
class_c(int my_max, int my_min) {
max = my_max > 0 ? my_max : 10;
min = my_min > 0 && my_min < max ? my_min : 1;
}
class_c(int my_max, int my_min, int my_middle) {
max = my_max > 0 ? my_max : 10;
min = my_min > 0 && my_min < max ? my_min : 1;
middle = my_middle < max && my_middle > min ? my_middle : 5;
}
};
您可以藉由新增會執行所有驗證的函式來減少重複程式碼,但如果某個建構函式可以將部分工作委派給另一個建構函式,則程式碼 class_c
會更容易理解和維護。 若要新增委派建構函式,請使用 constructor (. . .) : constructor (. . .)
語法:
class class_c {
public:
int max;
int min;
int middle;
class_c(int my_max) {
max = my_max > 0 ? my_max : 10;
}
class_c(int my_max, int my_min) : class_c(my_max) {
min = my_min > 0 && my_min < max ? my_min : 1;
}
class_c(int my_max, int my_min, int my_middle) : class_c (my_max, my_min){
middle = my_middle < max && my_middle > min ? my_middle : 5;
}
};
int main() {
class_c c1{ 1, 3, 2 };
}
當您逐步執行上述範例時,請注意建構函式會先呼叫 建構 class_c(int, int, int)
函 class_c(int, int)
式 ,接著會呼叫 class_c(int)
。 每個建構函式只會執行其他建構函式未執行的工作。
第一個呼叫的建構函式會初始化 物件,以便在該時間點初始化其所有成員。 您無法在委派給另一個建構函式的建構函式中執行成員初始化,如下所示:
class class_a {
public:
class_a() {}
// member initialization here, no delegate
class_a(string str) : m_string{ str } {}
//can't do member initialization here
// error C3511: a call to a delegating constructor shall be the only member-initializer
class_a(string str, double dbl) : class_a(str) , m_double{ dbl } {}
// only member assignment
class_a(string str, double dbl) : class_a(str) { m_double = dbl; }
double m_double{ 1.0 };
string m_string;
};
下一個範例顯示非靜態資料成員初始化運算式的使用。 請注意,如果建構函式也會初始化指定的資料成員,則會覆寫成員初始化運算式:
class class_a {
public:
class_a() {}
class_a(string str) : m_string{ str } {}
class_a(string str, double dbl) : class_a(str) { m_double = dbl; }
double m_double{ 1.0 };
string m_string{ m_double < 10.0 ? "alpha" : "beta" };
};
int main() {
class_a a{ "hello", 2.0 }; //expect a.m_double == 2.0, a.m_string == "hello"
int y = 4;
}
建構函式委派語法不會防止意外建立建構函式遞迴 —建構函式1 會呼叫建構函式2,而且在發生堆疊溢位之前,不會擲回任何錯誤。 這是你避免週期的責任。
class class_f{
public:
int max;
int min;
// don't do this
class_f() : class_f(6, 3){ }
class_f(int my_max, int my_min) : class_f() { }
};
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應