標籤:程式 函數 font view 先來 總結 xpl private 預設值
參考:http://www.weixueyuan.net/view/6343.html
總結:
帶參數的建構函式中有兩種比較常見的建構函式:拷貝建構函式和轉型建構函式。
轉型建構函式只有一個參數,如果該參數是int型,則我們是將int型對象轉換為類對象。
直接強制關閉掉這種隱式類型轉換,在C++中,通過關鍵字explicit可以實現該功能。
在C++中, 如果的建構函式只有一個參數時, 那麼在編譯的時候就會有一個預設的轉換操作:將該建構函式對應資料類型的資料轉換為該類對象。
C++中的explicit關鍵字只能用於修飾只有一個參數的類建構函式, 它的作用是表明該建構函式是顯示的, 而非隱式的, 跟它相對應的另一個關鍵字是implicit, 意思是隱藏的,類建構函式預設情況下即聲明為implicit(隱式).
explicit關鍵字只對有一個參數的類建構函式有效, 如果類建構函式參數大於或等於兩個時, 是不會產生隱式轉換的, 所以explicit關鍵字也就無效了.
但是, 也有一個例外, 就是當除了第一個參數以外的其他參數都有預設值的時候, explicit關鍵字依然有效, 此時, 當調用建構函式時只傳入一個參數, 等效於只有一個參數的類建構函式。
在前面,我們已經將建構函式劃分為兩類:預設建構函式(不帶參數的建構函式)和帶參建構函式。其中帶參數的建構函式中有兩種比較常見的建構函式:拷貝建構函式和轉型建構函式。我們先來瞭解一下轉型建構函式。
轉型建構函式用於類型間的轉換,將其它資料類型轉變為類的物件類型。轉型建構函式只有一個參數,如果該參數是int型,則我們是將int型對象轉換為類對象,如果該參數類型為char *類型,我們則是將字串常量轉換為類對象。
例1:
- class Age
- {
- public:
- Age(int a){age = a;}
- private :
- int age;
- }
在本例中Age(int a)即為一個轉型建構函式,該建構函式僅有一個參數,該建構函式是將int型轉換為類物件類型的。
例2:
- class student
- {
- public:
- student(){}
- student(char * n){name = n;}
- private :
- char * name;
- }
在本例中,student類中有兩個建構函式,一個是預設建構函式,另一個是轉型建構函式,該建構函式將字串常量轉換為類物件類型。
假設我們在程式設計過程中有一個以類對象作為函數參數的函數,函式宣告如下:
- void fun(student s); //函式宣告
如果我們設計了如下程式以調用該函數:
- char * name = “Harry Potter”;
- fun(name);
在例2中我們恰好在student類中定義了這樣一個轉型建構函式student(char * n);,該函數可以將字串常量轉換為student類的對象。在我們運行fun(name);語句時,編譯器會自動調用轉型建構函式將name轉換為student類的對象,然後調用void fun(student s);函數。這一系列的過程都是編譯器自動完成的,我們稱此時的student類的轉型建構函式student(char * n);支援隱式類型轉換。之所以說是隱式的,是因為這個轉型過程完全由編譯器完成,無需程式設計人員顯示轉換類型。
隱式類型轉換給程式設計人員帶來了一定的便利,但是隱式類型轉換可能會給我們設計的程式帶來一些難以覺察的細微錯誤。有時候我們為了避免這種錯誤,我們希望直接強制關閉掉這種隱式類型轉換,在C++中,通過關鍵字explicit可以實現該功能。
例3:
- class student
- {
- public:
- student(){}
- explicit student(char * n){name = n;}
- private :
- char * name;
- }
如例3所示,我們在轉型建構函式前加上了explicit關鍵字,如此一來,我們再想通過以下語句:
- char * name = “Harry Potter”;
- fun(name);
調用void fun(student s);函數則是無法通過編譯的,因為fun函數的參數是student類的對象而非字串常量,並且student類的轉型建構函式被標記為explicit,因此無法隱式地將字串常量轉換為student 類對象。使用explicit關鍵字的好處就在於將難以察覺的後期運行時可能會出現的錯誤提前到了編譯期,如此一來改正錯誤就比較容易了。
2.11 C++轉型建構函式