MoreEffectiveC++:避免缺省構(gòu)造函數(shù)

字號(hào):

缺省構(gòu)造函數(shù)(指沒(méi)有參數(shù)的構(gòu)造函數(shù))在C++語(yǔ)言中是一種讓你無(wú)中生有的方法。構(gòu)造函數(shù)能初始化對(duì)象,而缺省構(gòu)造函數(shù)則可以不利用任何在建立對(duì)象時(shí)的外部數(shù)據(jù)就能初始化對(duì)象。有時(shí)這樣的方法是不錯(cuò)的。例如一些行為特性與數(shù)字相仿的對(duì)象被初始化為空值或不確定的值也是合理的,還有比如鏈表、哈希表、圖等等數(shù)據(jù)結(jié)構(gòu)也可以被初始化為空容器。
    但不是所有的對(duì)象都屬于上述類(lèi)型,對(duì)于很多對(duì)象來(lái)說(shuō),不利用外部數(shù)據(jù)進(jìn)行完全的初始化是不合理的。比如一個(gè)沒(méi)有輸入姓名的地址簿對(duì)象,就沒(méi)有任何意義。在一些公司里,所有的設(shè)備都必須標(biāo)有一個(gè)公司ID號(hào)碼,所以在建立對(duì)象以模型化一個(gè)設(shè)備時(shí),不提供一個(gè)合適的ID號(hào)碼,所建立的對(duì)象就根本沒(méi)有意義。
    在一個(gè)完美的世界里,無(wú)需任何數(shù)據(jù)即可建立對(duì)象的類(lèi)可以包含缺省構(gòu)造函數(shù),而需要數(shù)據(jù)來(lái)建立對(duì)象的類(lèi)則不能包含缺省構(gòu)造函數(shù)。唉!可是我們的現(xiàn)實(shí)世界不是完美的,所以我們必須考慮更多的因素。特別是如果一個(gè)類(lèi)沒(méi)有缺省構(gòu)造函數(shù),就會(huì)存在一些使用上的限制。
    請(qǐng)考慮一下有這樣一個(gè)類(lèi),它表示公司的設(shè)備,這個(gè)類(lèi)包含一個(gè)公司的ID代碼,這個(gè)ID代碼被強(qiáng)制做為構(gòu)造函數(shù)的參數(shù):
    class EquipmentPiece {
    public:
    EquipmentPiece(int IDNumber);
    ...
    };
    因?yàn)镋quipmentPiece類(lèi)沒(méi)有一個(gè)缺省構(gòu)造函數(shù),所以在三種情況下使用它,就會(huì)遇到問(wèn)題。第一中情況是建立數(shù)組時(shí)。一般來(lái)說(shuō),沒(méi)有一種辦法能在建立對(duì)象數(shù)組時(shí)給構(gòu)造函數(shù)傳遞參數(shù)。所以在通常情況下,不可能建立EquipmentPiece對(duì)象數(shù)組:
    EquipmentPiece bestPieces[10]; // 錯(cuò)誤!沒(méi)有正確調(diào)用
    // EquipmentPiece 構(gòu)造函數(shù)
    EquipmentPiece *bestPieces =
    new EquipmentPiece[10]; // 錯(cuò)誤!與上面的問(wèn)題一樣
    不過(guò)還是有三種方法能回避開(kāi)這個(gè)限制。對(duì)于使用非堆數(shù)組(non-heap arrays)(即不在堆中給數(shù)組分配內(nèi)存。譯者注)的一種解決方法是在數(shù)組定義時(shí)提供必要的參數(shù):
    int ID1, ID2, ID3, ..., ID10; // 存儲(chǔ)設(shè)備ID號(hào)的
    // 變量
    ...
    EquipmentPiece bestPieces[] = { // 正確, 提供了構(gòu)造
    EquipmentPiece(ID1), // 函數(shù)的參數(shù)
    EquipmentPiece(ID2),
    EquipmentPiece(ID3),
    ...,
    EquipmentPiece(ID10)
    };
    不過(guò)很遺憾,這種方法不能用在堆數(shù)組(heap arrays)的定義上。一個(gè)更通用的解決方法是利用指針數(shù)組來(lái)代替一個(gè)對(duì)象數(shù)組:
    typedef EquipmentPiece* PEP; // PEP 指針指向
    //一個(gè)EquipmentPiece對(duì)象
    PEP bestPieces[10]; // 正確, 沒(méi)有調(diào)用構(gòu)造函數(shù)
    PEP *bestPieces = new PEP[10]; // 也正確