天天看點

Cookbook系列之Cpp:類

問題01:如何初始化成員變量?

    你應該總是在構造函數的初始化清單中初始化成員變量,并且避免在構造函數體中進行成員變量的初始化工作。如果這個成員變量是一個類,在初始化清單中進行初始化,隻需要一次構造操作;如果在函數體中進行初始化,則需要一次構造和一次指派操作。此外,初始化清單還可以使你獲得自動的異常處理。

    引用變量的初始化必須使用初始化清單。根據标準,一個引用必須一直指向一個簡單變量,并且不能被改變指向另一個變量。對于非成員變量,編譯器要求引用變量在進行定義時必須初始化它,使得它指向某個對象。而對于成員變量,大部分編譯都可以接受它直到你建立一個這個類的執行個體為止。

問題02:如何使用構造函數和析構函數管理資源

    在構造函數中配置設定資源或擷取資源,并在析構函數中釋放資源,這種技術常常稱為資源擷取初始化(RAII)。采用這種技術可以減少使用者的異常處理代碼。

問題03:在不需要類的使用者做任何特别處理的情況下,如何在一個容器中存儲該類的所有執行個體

    使用一個靜态的連結清單來存儲指向對象的指針。當一個對象被建立時,把它的位址加到這個連結清單中;而當這個對象被銷毀時,從這個連結清單中删除它。

問題04:在運作時,如何動态地查詢某個類對象的類型

    使用運作時類型辨別(RTTI)來查詢一個對象的位址以得到這個位址指向的對象類型。不過,RTTI是增加系統開銷的。

問題05:如何确定某個對象的類是否是另一個類的子類

    使用dynamic_cast操作符來擷取一個類型到另外一個類型的繼承關系,dynamic_cast帶一個指針或引用參數,并且企圖把它轉換成它的一個派生類的指針或者引用(downcast)。如果downcast是安全的(也就說,如果基類指針或者引用确實指向一個派生類對象)這個運算符會傳回适當轉型過的指針。如果downcast不安全,這個運算符會傳回空指針(也就是說,基類指針或者引用沒有指向一個派生類對象)。

問題06:如何實作一個隻能被執行個體化一次的類,即單例模式

    建立一個靜态成員變量并且這個成員是一個指向目前類的指針,通過private私有修飾符來限制構造函數的使用來建立這個類的對象,并且提供一個公有的靜态成員函數來通路這個唯一的執行個體。

問題07:如何定義一個子類将來可以實作的接口

    通過建立一個抽象基類(常常用ABC來稱呼)來定義這個接口,客戶代碼能夠用不同的實作來繼承這個抽象基類進而保證這個共同的接口。

    一個抽象基類是一個不能被執行個體化的類,是以它也就是起到一個接口的作用。如果一個類聲明了最少一個純虛函數或者它繼承了一個純虛函數但沒有它的實作的話,那麼這個類就是抽象類。是以,如果這個ABC的一個子類要執行個體的話,它不得不實作ABC類中所有的虛函數。

    最後,如果在你的基類中提供了虛的析構函數,你需要給它提供一個函數體。這是因為子類的析構函數需要自動調用基類的析構函數。

問題08:如何實作一個簡單成員函數,這個成員函數可以帶一個任意類型的參數

    使用成員函數模闆并且把這個模闆的參數聲明成這個成員函數的參數對象類型。調用示例中的get1()函數需要提供模闆參數,而調用get2()函數則不需要提供模闆參數。因為編譯器隻能通過形參來推導出模闆參數類型,get1()函數沒有形參,是以編譯器無法自動推導出傳回值類型。

問題09:如何調用一個特定類的超類中的函數,這個函數在子類被重寫了

    使用你的目标基類來修飾你的成員函數名

繼續閱讀