C++中的顯式構造函數

 有以下一個簡單的複數類:函數

class ClxComplex { public: ClxComplex(double dReal = 0.0, double dImage = 0.0) { m_dReal = dReal; dImage = dImage; } double GetReal() const { return m_dReal; } double GetImage() const { return m_dImage; } private: double m_dReal; double m_dImage; };

 

    咱們知道,下面的3行代碼是等價的:spa

ClxComplex lxTest = 2.0; ClxComplex lxTest = ClxComplex(2.0); ClxComplex lxTest = ClxComplex(2.0, 0.0);

 

    其實,對於前兩行來講,編譯器都是把它們轉換成第3行的代碼來實現的。由於咱們寫了構造函數,編譯器就按照咱們的構造函數來進行隱式轉換,直接把一個double數值隱式轉換成了一個ClxComplex的對象。但是,有些時候,咱們不但願進行隱式轉換,或者隱式轉換會形成錯誤。好比下面的一個簡化的字符串類:code

class ClxString { public: ClxString(int iLength); ClxString(const char *pString); ~ClxString(); private: char *m_pString; }; ClxString::ClxString(int iLength) { if (iLength > 0) m_pString = new char[iLength]; } ClxString::ClxString(const char *pString) { m_pString = new char[strlen(pString)]; strcpy(m_pString, pString); } ClxString::~ClxString() { if (m_pString != NULL) delete m_pString; }

 

    咱們能夠用字符串的長度來初始化一個ClxString的對象,可是咱們卻不但願看到下面的代碼:對象

ClxString lxTest = 13;  // 等同於ClxString lxTest = ClxString(13);

 

    這會給閱讀代碼形成沒必要要的歧義。

    還有,咱們知道下面的代碼是用字符串A來初始化一個ClxString的對象:blog

ClxString lxTest = "A";  // 等同於ClxString lxTest = ClxString("A");

 

    但是,若是有人寫成:
ClxString lxTest = 'A';  // 等同於ClxString lxTest = ClxString(65);

 

    那上面的代碼就會初始化一個長度爲65(字母A的ASCII碼值,在C和C++中,字符是以ASCII值存儲的)的字符串。

    固然,上面的狀況都不是咱們但願看到的。在這個時候咱們就要用到顯示構造函數了。
    將構造函數聲明成explicit就能夠防止隱式轉換。
    下面是使用顯示構造函數的ClxString:ci

class ClxString { public: explicit ClxString(int iLength); ClxString(const char *pString); ~ClxString(); private: char *m_pString; };

 

    在這種狀況下,要想用字符串的長度來初始化一個ClxString對象,那就必須顯示的調用構造函數:字符串

ClxString lxTest = ClxString(13);

 

    而下面這些代碼將不能經過編譯。
ClxString lxTest = 13; ClxString lxTest = 'A';
相關文章
相關標籤/搜索