僅含一個參數的構造函數和除了第一個參數外其余參數都有默認值的多參構造函數承擔了兩個角色。
1. 是個構造函數;2 .是個默認且隱含的類型轉換操作符。
explicit是個C++關鍵字,其作用是指定僅有一個參數或除第一個參數外其它參數均有默認值的類構造函數不能作為類型轉化操作符被隱含的使用,防止該類的對象直接被對應內置類型隱式轉化后賦值,從而規定這個構造函數必須被明確調用。
我們通過例子來直觀的說明:
#include <iostream> using namespace std; class A { public: A(int i = 5) { m_a = i; } private: int m_a; }; int main() { A s; //我們會發現,我們沒有重載'='運算符,但是卻可以把內置的int類型賦值給了對象A. s = 10; //實際上,10被隱式轉換成了下面的形式,所以才能這樣. //s = A temp(10); system("pause"); return 0; }
此時,我們發現s的成員變量m_a已將被更改了。
看看我們在類A的構造函數前加上explicit關鍵字會發生什么。
#include <iostream> using namespace std; class A { public: //這里用explicit關鍵詞來修飾類構造函數. explicit A(int i = 5, int j = 10) { m_a = i; m_b = j; } private: int m_a; int m_b; }; int main() { A s; //這樣直接賦值,會被提示錯誤,因為explicit抑制隱式轉換的進行 s = 10;//這樣會報錯!!! //當然顯示轉換還是可以的. s = A(20); system("pause"); return 0; }
再來看一個例子。
#include <iostream> using namespace std; class Test1 { public : Test1(int num):n(num){} private: int n; }; class Test2 { public : explicit Test2(int num):n(num){} private: int n; }; int main() { Test1 t1 = 12; Test2 t2(13); Test2 t3 = 14; return 0; }
編譯時t3那一行會報錯:提示:無法從“int”轉化為“Test2”。注釋掉t3那一行,t1能編譯通過,調試時發現t1中的成員變量n已被賦值成功。
通過以上兩個例子我們可得:對於僅有一個參數或除第一個參數外其余參數均有默認值的類構造函數,盡可能使用explicit關鍵字修飾。
另注意:當類的構造函數的聲明和定義分別在兩個文件里時,explicit只能寫在構造函數的聲明中,不能寫在定義中。