c++中
explicit
技術探索
c++程式語言中有很多比較重要的關鍵字在實際程式設計中起著非常重要的作用。我們今天為大家介紹的c++explicit關鍵字就是其中乙個應用比較頻繁的關鍵字。
按照預設規定,只有乙個引數的建構函式也定義了乙個隱式轉換,將該建構函式對應資料型別的資料轉換為該類物件,如下面所示:
class string
public:
string ( const char* pstring ); // 用c
風格的字串
p作為初始化值
~string();
private:
char *m_pstring;
string s1 = 「hello」; //ok 隱式轉換,等價於
string s1 = string
(「hello」);
但是有的時候可能會不需要這種隱式轉換,如下:
class string
string ( int nlength); //本意是預先分配
n個位元組給字串
string ( const char* pstring ); // 用c
風格的字串
p作為初始化值
~string();
private:
char *m_pstring;
string::string(int nlength)
if(nlength > 0)
m_pstring = new char[nlength];
}string::string(char *pstring)
pstring = new char[strlen(pstring)];
strcpy(m_pstring, pstring);
string::~string()
if(m_pstring != nuu)
delete m_pstring;}}
下面兩種寫法比較正常:
string s2 ( 10 ); //ok 分配
10個位元組的空字串
string s3 = string ( 10 ); //ok 分配
10個位元組的空字串
下面兩種寫法就比較疑惑了:
string s4 = 10; //編譯通過,也是分配
10個位元組的空字串
string s5 = 『a』; //編譯通過,分配
int(
『a』)個位元組的空字串
s4 和
s5 分別把乙個
int型和
char
型,隱式轉換成了分配若干位元組的空字串,容易令人誤解。為了避免這種錯誤的發生,我們可以宣告顯示的轉換,使用explicit 關鍵字:
class string
explicit string ( int nlength ); //本意是預先分配
n個位元組給字串
string ( const char* p ); // 用c
風格的字串
p作為初始化值
~string();
加上explicit,就抑制了string ( int n )
的隱式轉換,
下面兩種寫法仍然正確:
string s2 ( 10 ); //ok 分配
10個位元組的空字串
string s3 = string ( 10 ); //ok 分配
10個位元組的空字串
下面兩種寫法就不允許了:
string s4 = 10; //編譯不通過,不允許隱式的轉換
string s5 = 『a』; //編譯不通過,不允許隱式的轉換
因此,某些時候,explicit 可以有效得防止建構函式的隱式轉換帶來的錯誤或者誤解
在c++
中,如果乙個類有只有乙個引數的建構函式,
c++
允許一種特殊的宣告類變數的方式。在這種情況下,可以直接將乙個對應於構造函式引數型別的資料直接賦值給類變數,編譯器在編譯時會自動進行型別轉換,將對應於構造函式引數型別的資料轉換為類的物件。如果在建構函式前加上
explicit
修飾詞,則會禁止這種自動轉換,在這種情況下, 即使將對應於構造函式引數型別的資料直接賦值給類變數,編譯器也會報錯。
explicit只對建構函式起作用,用來抑制隱式轉換。如:
class a
;
int function(a a);
當呼叫function(2)
的時候,
2會隱式轉換為
a型別。這種情況常常不是程式設計師想要的結果,所以,要避免之就可以這樣寫:
class a
explicit a(int a);
};
int function(a a);
這樣,當呼叫function(2)
的時候,編譯器會給出錯誤資訊(除非
function
有個以int
為引數的過載形式),這就避免了在程式設計師毫不知情的情況下出現錯誤。
c++ explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的,既然有"顯式"那麼必然就有"隱式",那麼什麼是顯示而什麼又是隱式的呢?如果c++類的建構函式有乙個引數,那麼在編譯的時候就會有乙個預設的轉換操作:將該建構函式對應資料型別的資料轉換為該類物件,如下面所示:
class myclass
myclass obj = 10; //ok,convert int to myclass
在上面的**中編譯器自動將整型轉換為myclass類物件,實際上等同於下面的操作:
myclass temp(10);
myclass obj = temp;
上面的所有的c++ explicit關鍵字相關的操作即是所謂的"隱式轉換"。
如果要避免這種自動轉換的功能,我們該怎麼做呢?這就是關鍵字explicit的作用了,將類的建構函式宣告為"顯式",也就是在宣告建構函式的時候前面新增上explicit即可,這樣就可以防止這種自動的轉換操作,如果我們修改上面的myclass類的建構函式為顯式的,那麼下面的**就不能夠編譯通過了,如下所示:
class myclass
myclass obj = 10; //err,can't non-explict convert
c++中,乙個引數的建構函式(
或者除了第乙個引數外其餘引數都有預設值的多參建構函式)
,承擔了兩個角色.
(a)構造器
(b)預設且隱含的型別轉換操作符
寫下如aaa = ***
,這樣的**,且恰好
***的型別正好是
aaa單引數構造的引數型別,這時候編譯器就自動呼叫這個構造器,建立乙個
aaa的物件.
將拷貝建構函式宣告為explicit
,則會阻止隱式拷貝建構函式的呼叫。隱式拷貝建構函式的呼叫主要發生在三個點:
1.乙個物件作為函式引數,以值傳遞的方式傳入函式體.
2.乙個物件作為函式返回值,以值傳遞的方式從函式返回.
3.以aaa = ***
的方式建立物件
aaa,
***為與
aaa為同型別的物件.
因而,將拷貝建構函式宣告成explicit
並不是良好的設計,一般只將有單個引數的
constructor
宣告為explicit
,而copy constructor
不要宣告為
explicit.
C 中 explicit的用法
explicit 是避免建構函式的引數自動轉換為類物件的識別符號 cpp view plain copy include using namespace std class a intmain 上面的 編譯不成功,原因是當顯式地定義了乙個帶乙個引數的建構函式 帶explicit 必須要顯示地呼叫建構...
C 中 explicit顯示轉換
explicit 是避免建構函式的引數自動轉換為類物件的識別符號 cpp view plain copy include using namespace std class a intmain 上面的 編譯不成功,原因是當顯式地定義了乙個帶乙個引數的建構函式 帶explicit 必須要顯示地呼叫建構...
C 中explicit的作用
explicit作用 在c 中,explicit關鍵字用來修飾類的建構函式,被修飾的建構函式的類,不能發生相應的隱式型別轉換,只能以顯示的方式進行型別轉換。explicit使用注意事項 1.explicit 關鍵字只能用於類內部的建構函式宣告上 2.explicit 關鍵字作用於單個引數的建構函式 ...