MoreEffectiveC++:不使用多態(tài)性數(shù)組

字號(hào):

類繼承的最重要的特性是你可以通過(guò)基類指針或引用來(lái)操作派生類。這樣的指針或引用具有行為的多態(tài)性,就好像它們同時(shí)具有多種形態(tài)。C++允許你通過(guò)基類指針和引用來(lái)操作派生類數(shù)組。不過(guò)這根本就不是一個(gè)特性,因?yàn)檫@樣的代碼根本無(wú)法如你所愿地那樣運(yùn)行。
    假設(shè)你有一個(gè)類BST(比如是搜索樹(shù)對(duì)象)和繼承自BST類的派生類BalancedBST:
    class BST { ... };
    class BalancedBST: public BST { ... };
    在一個(gè)真實(shí)的程序里,這樣的類應(yīng)該是模板類,但是在這個(gè)例子里并不重要,加上模板只會(huì)使得代碼更難閱讀。為了便于討論,我們假設(shè)BST和BalancedBST只包含int類型數(shù)據(jù)。
    有這樣一個(gè)函數(shù),它能打印出BST類數(shù)組中每一個(gè)BST對(duì)象的內(nèi)容:
    void printBSTArray(ostream& s,
    const BST array[],
    int numElements)
    {
    for (int i = 0; i < numElements; ) {
    s << array[i]; //假設(shè)BST類
    } //重載了操作符<<
    }
    當(dāng)你傳遞給該函數(shù)一個(gè)含有BST對(duì)象的數(shù)組變量時(shí),它能夠正常運(yùn)行:
    BST BSTArray[10];
    ...
    printBSTArray(cout, BSTArray, 10); // 運(yùn)行正常
    然而,請(qǐng)考慮一下,當(dāng)你把含有BalancedBST對(duì)象的數(shù)組變量傳遞給printBSTArray函數(shù)時(shí),會(huì)產(chǎn)生什么樣的后果:
    BalancedBST bBSTArray[10];
    ...
    printBSTArray(cout, bBSTArray, 10); // 還會(huì)運(yùn)行正常么?
    你的編譯器將會(huì)毫無(wú)警告地編譯這個(gè)函數(shù),但是再看一下這個(gè)函數(shù)的循環(huán)代碼:
    for (int i = 0; i < numElements; ) {
    s << array[i];
    }
    這里的array[I]只是一個(gè)指針?biāo)惴ǖ目s寫(xiě):它所代表的是*(array)。我們知道array是一個(gè)指向數(shù)組起始地址的指針,但是array中各元素內(nèi)存地址與數(shù)組的起始地址的間隔究竟有多大呢?它們的間隔是i*sizeof(一個(gè)在數(shù)組里的對(duì)象),因?yàn)樵赼rray數(shù)組[0]到[I]間有I個(gè)對(duì)象。編譯器為了建立正確遍歷數(shù)組的執(zhí)行代碼,它必須能夠確定數(shù)組中對(duì)象的大小,這對(duì)編譯器來(lái)說(shuō)是很容易做到的。參數(shù)array被聲明為BST類型,所以array數(shù)組中每一個(gè)元素都是BST類型,因此每個(gè)元素與數(shù)組起始地址的間隔是be i*sizeof(BST)。
    至少你的編譯器是這么認(rèn)為的。但是如果你把一個(gè)含有BalancedBST對(duì)象的數(shù)組變量傳遞給printBSTArray函數(shù),你的編譯器就會(huì)犯錯(cuò)誤。在這種情況下,編譯器原先已經(jīng)假設(shè)數(shù)組中元素與BST對(duì)象的大小一致,但是現(xiàn)在數(shù)組中每一個(gè)對(duì)象大小卻與BalancedBST一致。派生類的長(zhǎng)度通常都比基類要長(zhǎng)。我們料想BalancedBST對(duì)象長(zhǎng)度的比BST長(zhǎng)。如果如此的話,printBSTArray函數(shù)生成的指針?biāo)惴▽⑹清e(cuò)誤的,沒(méi)有人知道如果用BalancedBST數(shù)組來(lái)執(zhí)行printBSTArray函數(shù)將會(huì)發(fā)生什么樣的后果。不論是什么后果都是令人不愉快的。