2015-05-01 131 views
0

我想知道以下兩個類設計選擇中的一個在性能和/或可維護性方面是否優越,或者其他問題會優於其他問題。C++類繼承設計選擇

第一種方法:

基類(父)具有私有數據成員和一個純虛擬無效的功能。子類(childA)將參數從其默認構造函數傳遞給父類,並使用父類的getter方法打印出其他值。

第二種方法:

基類(ONCLE)只由一個virual析構函數和純虛方法。子類(侄子)擁有商店作爲私人數據成員的價值,並具有自己的getter函數來執行某些計算。

下面是一些代碼:

#include <iostream> 

class parent{ 
public: 
    parent(int x){ _x = x; } 
    virtual ~parent(){} 
    virtual void calc(void) = 0; 
    int getX(void) { return _x; } 
private: 
    int _x; 
}; 

class childA: public parent{ 
public: 
    childA(int x): parent(x){} 
    void calc(void){std::cout << "x sq: " << parent::getX()*parent::getX() << std::endl;} 
}; 


class oncle{ 
public: 
    virtual ~oncle(){} 
    virtual void calc(void) = 0; 
}; 

class nephewA: public oncle{ 
public: 
    nephewA(int x): _x(x){} 
    void calc(void){std::cout << "x sq: " << getX()*getX() << std::endl;} 
    int getX(void){ return _x; } 
private: 
    int _x; 
}; 

int main(int argc, char *argv[]) 
{ 

    parent *first = new childA(3); 
    parent *second = new childB(3); 

    first->calc(); 
    second->calc(); 

    oncle *foo = new nephewA(3); 
    oncle *bar = new nephewB(3); 
    foo->calc(); 
    bar->calc(); 


    delete bar; 
    delete foo; 
    delete second; 
    delete first; 

    return 0; 
} 

總之:第一種方法就是將重點放在家長和第二子類中。

那麼是否有任何可量化的方面可以幫助我選擇兩種方法之一?

+3

應用程序應該確定需要什麼方法。 – NathanOliver

+2

可能轉移到[email protected] –

+0

這個問題只是一場辯論。不應該在這一部分。 – Khaldor

回答

1

性能:

一般來說,性能問題,在很大程度上取決於編譯器的優化,應該由最好的一個特設的基準來解決。

然而,對於這個簡單的例子,很明顯,這兩種方法的性能應該是相同的:

  • 方法1:calc()每個呼叫是虛擬呼叫(間接函數調用)。該函數調用兩次父代的getX(),這是一個非虛函數調用(即每個calc()在編譯時知道它必須調用哪個函數)在編譯時完全確定。
  • 方法2:calc()的每次調用也是一個虛擬調用(間接函數調用)。該函數調用對象的getX()兩次,這是一個非虛函數調用,在編譯時完全確定。

另外,編譯器可以非常容易地在這裏內聯非虛函數。所以優化過的代碼肯定不會調用這個函數,而是直接使用這個變量。

可維護性

你應該問自己多少成員(X /的getX())真的綁定到其所定義的類,怎麼可能是你的設計的每一個元素可以發展。

  • 方法1假設x是管理所有的孩子們以同樣的方式,沒有例外。
    • 如果是這種情況,這種設計具有集中維護的優點。例如,如果明天你需要x變成雙倍,那麼實施這樣的演變將會很順利。
    • 如果這個基本假設會改變,你所要做的就是爲子女定義getX(),它應該有不同的行爲。唯一的缺點是,這些孩子仍然會有一個私人的x,這將保持不被使用。如果你有幾個對象,這不是一個嚴重的問題。如果你在內存中擁有數百萬個這樣的對象,這可能不是最理想的。
  • 方法2假設每一個侄子負責管理自己的getX()這是一個非常靈活的設計,尤其是如果有很多不同的規則:
    • 內存管理總是會針對每個侄子。如果一個侄子會例如從另一個值導出x,則不需要存儲冗餘信息。
    • 靈活性也可以有其缺點,特別是如果它不符合現實:它可能需要複製和粘貼許多侄子相同成員的相同定義。這樣的代碼將很難維護(因爲任何chagne to x或getX()都必須在所有侄子之間被複制)。

結論:

正如你看到的,沒有一個統一的最佳答案。這一切都取決於班級和成員之間的真正關係。

一些例子:

  • 如果父母是僱員,孩子及其在工作流程中的作用,x是年齡,我會去的方法1(x是一個真正與母體)。
  • 如果oncle是一個抽象的幾何形狀,newphew的具體形狀如方形/三角形/ octogon,並且x是最大寬度,我會爲方法2(x確實綁定到侄子)。
+0

謝謝你的詳細答案。 – Vincent