2011-11-22 17 views
0

私は4つのクラスを複数の継承菱形スキームの下に編成しました。C++多重継承(菱形スキーム)パラダイム

   BASE 
      /\ 
      / \ 
     Deriv1 Deriv2 
      \ /
      \/
      Final 

Iは、各クラスの 'XXXX' は、クラスの名前である "ShowXXXX()" メソッド(例えば)を有します。

私はそれを印刷し、 "ob.ShowFinal()" メソッドを呼び出す:

  • 決勝のフィールド、
  • Deriv1のフィールド、
  • ベースのフィールド、
  • Deriv2のフィールド、
  • ベースのフィールド

プロblem私はベースのフィールドを2度目に印刷してエスケープしたいということです。 しかし、パラダイムがある:私は「ob.ShowDeriv2()」を呼び出すときの原因には、印刷する必要があります。

  • Deriv2のフィールド、
  • ベースのフィールド

と私はそれがあるべき「ob.ShowDeriv1()」と呼びます印刷:

  • Deriv1のフィールド、
  • ベースのフィールド

マイコード:

// multipleInheritance.cpp : Defines the entry point for the console application. 
// 

//Summary: 
//  
//  Mmb - member 
//  Prm - parameter 
//  b - Base 
//  i1, i2 - Intermediate1, Intermediate2 
//  f - final 

class Base 
{ 
    int bMmb; 

public: 
    Base(int); 
    void ShowBase(); 
}; 

Base::Base (int bPrm) 
{ 
    bMmb = bPrm; 
} 

void Base::ShowBase() 
{ 
    cout << "Showing Base fields" << endl; 
    cout << "bMmb = " << bMmb << endl; 
    cout << "----------------------------" << endl << endl; 
} 

class Intermediate1 : public Base 
{ 
    int i1Mmb; 

public: 
    Intermediate1(int, int); 
    void ShowIntermediate1(); 
}; 

Intermediate1::Intermediate1(int bPrm, int i1Prm):Base(bPrm) 
{ 
    i1Mmb = i1Prm; 
} 

void Intermediate1::ShowIntermediate1() 
{ 
    cout << "Showing Intermediate1 fields" << endl; 
    cout << "i1Mmb = " << i1Mmb << endl; 
    ShowBase(); 
} 

class Intermediate2 : public Base 
{ 
    int i2Mmb; 

public: 
    Intermediate2(int, int); 
    void ShowIntermediate2(); 
}; 

Intermediate2::Intermediate2(int bPrm, int i2Prm):Base(bPrm) 
{ 
    i2Mmb = i2Prm; 
} 

void Intermediate2::ShowIntermediate2() 
{ 
    cout << "Showing Intermediate2 fields" << endl; 
    cout << "i2Mmb = " << i2Mmb << endl; 
    ShowBase(); 
} 

class Final : public Intermediate1, public Intermediate2 
{ 
    int fMmb; 

public: 
    Final(int, int, int, int); 
    void ShowFinal(); 
}; 

Final::Final(int bPrm, int i1Prm, int i2Prm, int fPrm): Intermediate1(bPrm, i1Prm), Intermediate2(bPrm, i2Prm) 
{ 
    fMmb = fPrm; 
} 

void Final::ShowFinal() 
{ 
    cout << "Showing Final fields" << endl; 
    cout << "fMmb = " << fMmb << endl; 
    ShowIntermediate1(); 
    ShowIntermediate2(); 
} 

void main() 
{ 
    Base t(1); 
    t.ShowBase(); 

    Intermediate1 u1(2, 31); 
    u1.ShowIntermediate1(); 

    Intermediate2 u2(4, 51); 
    u2.ShowIntermediate2(); 

    Final v(6, 71, 72, 8); 
    v.ShowFinal(); 
} 

が助けてくれてありがとう!

+0

仮想継承を使用して、非仮想継承のケースでは2つではなく、「最終」に1つの「BASE」サブオブジェクトが確実に得られるようにします。しかし、仮想継承にはコストがかかります。これは 'Deriv1'と' Deriv2'サブオブジェクトのサイズを増やし、使用するのにいくらか複雑です。そして私は考えるのを助けることはできませんが、あなたのデザインには根本的な問題があります。あなたは実際に何をしようとしていますか?すべての 'Show *()'メソッドはデバッグのためだけに存在しますか? –

+0

コンポジションを使用しているときに継承を使用しているような感じです。あなたはそのコードで解決しようとしている問題を説明できますか? –

+0

私は、私の教授が実験室トレーニングコースで提案した作業を行うべきです。彼が "菱形の形で多重継承をしようとする"という簡単な例です – meorfi

答えて

1

あなたの質問にはほとんど制約がないため、これはうまくいくはずです。

変更Intermediate1での宣言(2)

public: 
    void ShowIntermediate1(bool printBase = true); 

へと実装で:ShowFinal()で次に

... 
if (printBase) 
ShowBase(); 

ShowIntermediate1(true); 
ShowIntermediate2(false); 
0

たぶん答え、あなたが探していますforはvirtual inheritanceです。どちらが解決するように設計されていますdiamond problem。しかし、仮想メソッドを使用するようにコードを変更する必要があります。