2009-12-12 23 views
2

我發現我的自我在子構造函數中重複了一行代碼,它傳遞了兩個變量。這些變量中的第一個始終用於啓動受保護的變量(在父類中定義)。我想知道是否有一種方法可以讓我在父構造函數中執行該賦值 - 然後繼承該賦值,併爲每個相應構造函數中的子類的子項類別(在子類中)執行其餘的輔助操作子類中某些方法的C++高效繼承

這可能嗎?這是一個好習慣嗎?

千恩萬謝

+3

一些代碼可以解釋你在說什麼。 – shoosh 2009-12-12 01:18:44

回答

4

如果我理解正確的話,你需要像這樣

class Parent 
{ 
public: 
    Parent(int Param1, doubel param2) 
    :param1(Param1), param2(Param2) 
{ 
} 
protected: 
    int param1; 
    double param2; 
}; 

class Derived: public Parent 
{ 
public: 
    Derived(int Param1, doubel param2) 
    :Parent(Param1, Param2) 
    { 
    } 
}; 

我會建議保持參數1和參數私人和通過方式揭露他們的派生類,雖然這取決於的你手頭的特殊任務。

+0

+1用於暗示將變量保留爲私有 – xtofl 2009-12-12 11:52:53

1

你的意思是這樣的嗎?

class Parent { 
    Parent(const Foo& x) : x(x) {} 
    Foo x; 
}; 

class Child : Parent { 
    Child(const Foo& x, const Bar& y) : Parent(x), y(y) {} 
    Bar y; 
}; 

如果Parent擁有變量,使Parent的構造函數初始化。然後你的Child類只需將變量傳遞給Parent的構造函數。

0

如果你的意思是要解決這個問題

// an example base class, forcing some invariant on it's state 
class Base { 
    int i; // guaranteed to be zero or MAXINT 
public: 
    Base(bool isClear): i(isClear ? 0 : MAXINT) {} 
    void increment() { i = MAXINT; } 
    void decrement() { i = 0; } 

    bool isMax() const { return i == MAXINT; } 
    bool isZero() const { return i == 0; } 
    void checkInvariants() const { assert(isMax() || isZero()); } 
}; 

class Sub : public Base { 
public: 
    Sub(int intended_i) : i(intended_i) {} // error: i not accessible! 
}; 

通過使Base::i部件保護,你在一塊易碎的設計。這是Base班級對其成員進行初始化的責任。當將成員開放給子類或公衆時,Base不再能保證它的成員受其保持不變。

在上面的代碼,這將意味着Base某些情況下可能無法「行爲」就像Base實例:

Sub s(10); 
s.checkInvariants(); // will trigger the assert! 

最重要的是,子類必須決定改變時改變超級成員。

子類實際上也是基類的客戶端。他們應該訪問與客戶端代碼相同的接口。這保持了設計的靈活性(鬆耦合)。

一種反覆複製構造函數參數的方法是將其包裝在一個結構中。尤其是當你懷疑的基類須經常更換,這樣可以分離關注頗多:

class Base { 
    int i; 
public: 
    struct Args { bool isClear; }; 
    Base(const Args & args): i(args.isClear ? 0 : MAXINT) {} 
}; 

class Sub { 
    bool b; 
public: 
    struct Args { Base::Args base; bool b; }; 
    Sub(const Args& args): Base(args.base), b(args.b) {} 
}; 

現在,添加成員的基類,而不改變子成爲可能:簡單地延長Base::Args結構,你就完成了。 (注意:客戶端代碼仍然需要填寫基類的額外參數)。