小心C++編譯器給我們帶來的麻煩

字號:

有下面一個(gè)簡單的類:
    class ClxTest
    {
    public:
    ClxTest(int iSize = 13) { pszStr = new char[iSize]; };
    ~ClxTest() { if(pszStr) delete pszStr; };
    lxOutput() { cout << pszStr << endl; };
    private:
    char *pszStr;
    };
    現(xiàn)在有下面的兩行代碼:
    ClxTest *pTest = new ClxTest();
    ClxTest *pTest = new ClxTest;
    我想大家都知道,兩種方法的效果都是一樣的--都是聲明了一個(gè)指向類ClxTest的對象的指針,而在創(chuàng)建對象的時(shí)候,都是調(diào)用了類的默認(rèn)構(gòu)造函數(shù)。
    可是大家知道下面兩行代碼的區(qū)別嗎?
    ClxTest lxTest;
    ClxTest lxTest();
    如果你認(rèn)為,這兩行代碼都是聲明了一個(gè)類ClxTest的對象,在創(chuàng)建對象的時(shí)候也都是調(diào)用了類的默認(rèn)構(gòu)造函數(shù)的話,那你就大錯(cuò)特錯(cuò)了!不相信?那你可以試試下面的代碼:
    ClxTest lxTest();
    lxTest.lxOutput();
    也許你認(rèn)為上面的代碼沒有什么問題,可是事實(shí)是這些代碼根本不能通過編譯!因?yàn)镃++編譯器把ClxTest lxTest();這行代碼當(dāng)成了一個(gè)函數(shù)聲明!這個(gè)函數(shù)的名字是lxTest,沒有參數(shù),返回值的類型是ClxTest!
    很令人吃驚,對吧?但是這卻與C++中的一條普遍規(guī)律相符和--盡可能地解釋為函數(shù)聲明。
    如果說你不知道這些的話,當(dāng)代碼編譯不通過時(shí),你肯定會百思不得其解,也許要花好長時(shí)間也找不出錯(cuò)誤在什么地方。當(dāng)然,如果你的代碼是下面的形式,就不會出現(xiàn)編譯錯(cuò)誤了。
    ClxTest lxTest(13);
    lxTest.lxOutput();
    因?yàn)?,你指定了類?gòu)造函數(shù)的參數(shù)值,C++編譯器不能將ClxTest lxTest(13);這行代碼解釋為函數(shù)聲明,它就會去尋找合適的解釋而去調(diào)用類的構(gòu)造函數(shù)來創(chuàng)建對象。
    如果我們在創(chuàng)建類的對象時(shí)想使用構(gòu)造函數(shù)的默認(rèn)參數(shù)值,那么除了ClxTest lxTest;的聲明方式外,還有一種聲明方式ClxTest lxTest = ClxTest();,當(dāng)然這有點(diǎn)兒畫蛇添足了。