生活随笔
收集整理的這篇文章主要介紹了
深入理解C++中的explicit关键字
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
深入理解C++中的explicit關鍵字
kezunhai@gmail.com
http://blog.csdn.net/kezunhai
? ? ? ? ?C++中的explicit關鍵字 只能用于 修飾只有一個參數 的 構造函數 , 它的作用是表明該構造函數是顯示的 , 而非隱式的, 跟它相對應的另一個關鍵字是implicit , 意思是隱藏的,構造函數默認情況下即聲明為implicit(隱式)。
? ? ? ? ?關于explicit關鍵字,先看看MSDN上的解釋:
? ? ? ??This keyword is a declaration specifier that can?only be applied to in-class constructor declarations . An explicit constructor cannot take part in implicit conversions. It can?only be used to explicitly construct an object 。
? ? ? ? 從上面的解釋可以看到, explicit關鍵字的作用:禁止隱式調用類內的單參數構造函數, 這主要包括如下三層意思:
? ? ? ? ?(1)該關鍵字只能用來修飾類內部的構造函數
? ? ? ? ?(2)禁止隱式調用拷貝構造函數
? ? ? ? ?(3)禁止類對象之間的隱式轉換
??? ? ? ? ?首先,來看看隱式轉換,如下例:
[cpp]?view plaincopy
class ?CExplict?? {?? public :?? ????CExplict();?? ????CExplict(?bool ?_explicit)?? ????{?? ????????this ->is_explict?=?_explicit;?? ????}?? ????CExplict(const ?CExplict&?other)?? ????{?? ????????this ->is_explict?=?other.is_explict;?? ????}?? ????friend ? void ?printExplicit( const ?CExplict&?cx);//友元函數的實現可以在類外 定義, 但必須在類內部聲明 ? ?? private :?? ????bool ?is_explict;?? };?? ?? void ?printExplicit( const ?CExplict&?cx)?? {?? ????cout<<"is_explict=" <<cx.is_explict<<endl;?? }?? ?? int ?main(? int ?argc,? char *?argv[])?? {?? ????CExplict?cx1?=?true ;?? ????CExplict?cx2?=?cx1;?? ????printExplicit(cx1);?? ????printExplicit(cx2);?? ????printExplicit(false );?? ????getchar();?? ????return ?1;?? }??
? ? ? 在上面的代碼中:
[cpp]?view plaincopy
CExplict?cx1?=? true ;?? CExplict?cx2?=?cx1;?? printExplicit(false );??
隱式調用CExplict類的單參數構造函數。這種調用在C++語法中是允許的,但是諸如:CExplict cx1 = true和printExplicit(false)這種表達形式看著很別扭,也很讓人費解,將一個bool型的值賦給一個CExplicit類的cx1,使代碼的可讀性變差。
? ? ? ? ? 因此,為了禁止對類的單參數構造函數的隱式調用,C++引入了關鍵字explicit。在類的定義中,在任何一個單參數構造函數錢加explicit關鍵字,就可以禁止對該構造函數的隱式調用 。如下:
[cpp]?view plaincopy
class ?CExplict?? {?? public :?? ????CExplict();?? ????explicit ?CExplict(? bool ?_explicit)?? ????{?? ????????this ->is_explict?=?_explicit;?? ????}?? ????CExplict(const ?CExplict&?other)?? ????{?? ????????this ->is_explict?=?other.is_explict;?? ????}?? ????friend ? void ?printExplicit( const ?CExplict&?cx);???? ?? private :?? ????bool ?is_explict;?? };?? ?? void ?printExplicit( const ?CExplict&?cx)?? {?? ????cout<<"is_explict=" <<cx.is_explict<<endl;?? }?? ?? int ?main(? int ?argc,? char *?argv[])?? {?? ????CExplict?cx1?=?true ;?? ????CExplict?cx2?=?cx1;?? ????printExplicit(cx1);?? ????printExplicit(cx2);?? ????printExplicit(false );?? ????getchar();?? ????return ?1;?? }??
此時,在調用上面一段代碼,則會報:
?error C2440: “初始化”: 無法從“bool”轉換為“CExplict”的錯誤,為了使程序能正確運行,需要將main函數內的代碼改為:
[cpp]?view plaincopy
int ?main(? int ?argc,? char *?argv[])?? {?? ????CExplict?cx1(true );?? ????CExplict?cx2(cx1);?? ????printExplicit(cx1);?? ????printExplicit(cx2);?? ????printExplicit( CExplict (false ));?? ????getchar();?? ????return ?1;????? }??
至此,程序就可以正常運行,而且進一步增加了程序的可讀性。
? ? ? ? ?總結:
? ? ? ? (1)explicit關鍵字只需用于類內的單參數構造函數前面。由于無參數的構造函數和多參數的構造函數總是顯示調用,這種情況在構造函數前加explicit無意義。
? ? ? ? (2)如果想禁止類A對象被隱式轉換為類B對象,可在類B中使用關鍵字explicit,即定義這樣的轉換構造函數
[cpp]?view plaincopy
??????? explicit ?B(A?a)?? {?? ?? }?? explicit ?B( const ?A?&a)?? {?? ?? }??
? ? ? ? google的c++規范中提到explicit的優點是可以避免不合時宜的類型變換,缺點無。所以google約定所有單參數的構造函數都必須是顯示的,只有極少數情況下拷貝構造函數可以不聲明稱explicit。例如作為其他類的透明包裝器的類。
effective c++中說:被聲明為explicit的構造函數通常比其non-explicit兄弟更受歡迎。因為它們禁止編譯器執行非預期(往往也不被期望)的類型轉換 。除非我有一個好理由允許構造函數被用于隱式類型轉換,否則我會把它聲明為explicit,鼓勵大家遵循相同的政策。
作者: kezunhai 出處: http://blog.csdn.net/kezunhai 歡迎轉載或分享,但請務必聲明文章出處。
from:https://blog.csdn.net/kezunhai/article/details/38417087
總結
以上是生活随笔 為你收集整理的深入理解C++中的explicit关键字 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。