2011-07-06 58 views
0
struct A { 
    B b; 
    A(int x):b(x){} 
    A(int x, float g) // how to implement this? I want to init b as a C. 
}; 
struct B { 
    enum {e_c, e_d} type; 
    int i; 
    B(int i_):i(i_){} 
}; 
struct C : public B { 
    float f; 
    C(int i_, float f_):B(i),f(f_){} 
}; 
struct D : public B { 
    double ff; 
    D(int i_, double d):B(i),ff(d){} 
}; 

也許還有另一種方法來編碼?最初我只有B類,但我決定分割它,所以我沒有向B添加(不兼容/互斥)字段。我的解決方案是,當A使用b時,它檢查b的枚舉以查看它是什麼類型,然後將B *轉換爲C *或D *以獲得浮點數或雙精度值。我的問題是現在我不知道如何讓A初始化b。該語言甚至讓我做這樣的事情?用子類的ctor初始化

編輯:我剛剛意識到A的b不可能已經分配了空間來允許C或D的額外字段。沒有任何可用空間來存儲浮點數或雙精度值。所以我想正確的方式去做我想做的事情就是加入B union {float f; double ff;};

+0

由於您有一個類型爲「B」的實際對象成員,因此您不能將init初始化爲'C'!你**可以使對象成爲'B *',但爲什麼不直接讓'C'類型的成員? –

+0

無論如何,在基類中枚舉枚舉可能的派生類聞起來就像即將發生的設計車禍。如果您發佈實際問題,我們可以考慮更好的解決方案。 –

+0

我想用另一種方式來解釋我的問題是:還有更多的OOP方式來做一個工會嗎?我只知道如果我使用聯合,就像在這個例子中說的那樣,它有一個float和一個double,並且我將double值解釋爲一個float值,我會得到垃圾,這可能會使討厭的錯誤。 –

回答

2

你的例子有點困惑。但是,也許你想要一個指針?

struct A { 
    B *b; 
    A(int x):b(new B(x)) {} 
    A(int x, float g):b(new C(x,g)) {} 
    ~A() { delete b; } // Very important! 
}; 

請注意,如果你這樣做,B必須有一個虛析構函數。您還需要考慮複製A對象意味着什麼。

+0

**必須**提及'B'虛擬析構函數! :-)並且讓'A'在您處理時不可複製。另外,OP將enum放入'B'的想法使得它看起來像是即將到來的糟糕的設計選擇... –

+0

@Kerrek:啊,好點,沒有發現虛擬驅動器從OP的代碼中缺失。複製建築/作業可能很容易導致沿着花園路徑的切線,但我也會提到。 –

1

您的編輯是正確的。

可能正常的做法是按照(最好是智能)指針存儲B,並在相應的構造函數中分配正確的類型。