2016-10-14 6 views
1

プログラムの目的は、スピーカエンクロージャのシミュレーションスクリプトを生成することでした。親データメンバの値を子クラスに渡す

私はスピーカーを定義するクラススピーカーを持っています。

すべてのエンクロージャの共通パラメータを含む親クラスエンクロージャ。

自分自身の特別なプロパティを持つ子クラスです。親クラスのメンバーデータは私のプログラムの場合は

class speaker 
{  
} 
class Enclosure 
{ 
     int m_boxHeight; 
     speaker * m_speakerBass;//... 
     public://some functions 
} 
class closedBox : public Enclosure 
{   
    public: 
     closedbox(speaker &speakerbass):Enclosure(speakerbass)// some functions    
    protected: 
     int paramclosed1;//...    
} 

int main() 
{  
    speaker speakerbass; 

    cout <<endl<< "Please choose in the available enclosure proposals" << endl; 
    cout << "1 Closed box enclosure" << endl; 
    // cout << "2 Bass reflex enclosure" << endl; 
    // cout << "3 and so on..." << endl; 
    int choice; 
    cin>>choice; 
      switch (choice) 
     { 
     case 1: 
      closedbox * ClBox2Simu; 
      ClBox2Simu= new closedbox(speakerbass);  
      delete ClBox2Simu; 
      break; 
     case 2: 
      //... same but with bassreflex class child  
      break; 

     default: 
      cout<<"Then good bye"; 

     } 
    return 0; 
} 

ことができます:私は完全に正常に動作しますが、私は毎回エンクロージャの基本プロパティを再計算する必要がある最初のプログラムを取得した多型と継承を使用して

子どもに与えられる。つまり、Enclosureのボックスサイズは、各子クラスbassreflexまたはclosedboxで同じです。

への道があればこのように、私は今になります。

  • は親パラメータ(問題)を持つ子どもを作成するには、最初の最初の一般的な計算を行う親クラスを作成します

子=親は禁止されています。このコードのアイデアで :

class speaker 
{ 
    public:  // some functions 
    protected: 
     int fs; 
     int paramSpeaker2;   //...  
} 
class Enclosure 
{  
    public:   //some common function 
    protected: 
     int m_boxHeight; 
     speaker *m_speakerBass //...  
} 
class closedBox : public Enclosure 
{  
    public: 
     closedbox(); // some functions 
    protected: 
     int paramclosed1; //...  
} 
class bassreflex : public Enclosure 
{  
    public: 
     bassreflex(); // some functions 
    protected: 
     int paramclosed1; //...  
} 

int main() 
{  
    Enclosure initialBox;// calculate dimension,choose speaker... 

      closedbox * ClBox2Simu; 
      ClBox2Simu= initialBox;// child= parent which is forbidden 
      //do stuff concerning closedbox 
      delete ClBox2Simu; 

      bassreflex * BassReflex2Simu; 
      BassReflex2Simu= initialBox; //forbidden 
      //do stuff concerning bassreflex 
      delete BassReflex2Simu; 

      //... and so on for other child class using enclosure 

     delete initialBox 
    return 0; 
} 

が、それは明らかだホープ!

+2

なぜ子クラスを直接初期化しないのですか? [Constructors and Member Initializer List](http://en.cppreference.com/w/cpp/language/initializer_list) – Danh

+0

「基本プロパティの再計算」がどこで(または、なぜ)行われたのか分かりません。 – UnholySheep

+0

最初の例の動的割り当ては完全に不要です。 – molbdnilo

答えて

1

あなたが記述の症状は、典型的ながある-があり-、すなわち相続対構図の問題を示唆しています。

C++では、原則として子オブジェクトを作成します。子供の建設プロセスは次のとおりです。

  • 最初に囲まれた親オブジェクトは子のメンバーが
  • を構築し、最後に、子コンストラクタ本体が建設を完了するために実行され、その後
  • を構築しています。

このロジックに問題が発生するとすぐに、継承がおそらく最良の方法ではないことが示唆されます。 OOPの通常のアドバイスはよりもの方が優先します。原則として継承は、オブジェクトの性質が変わらない場合にのみ使用されるべきです。

お使いの場合には
class animal {}; 
class cat : public animal {}; // ok: a cat will always remain an animal 

class person {}; 
class employee : public person {}; // bad idea: a person could have several job 
            // or change job or (hopefully temporarily) without job 

// possible alternative 
class job_t { string title, company; date from,to; ... }; 
class person { vector<job_t> jobs; ... }; // very flexible 

、私はEnclosureは、いくつかの一般的なパラメータを持っていることを理解するだろうが、形状因子がある:私はここにあなたのドメイン、典型的な、より身近な例に慣れていないんだと

波が環境にどのように伝達されるか、そして他のいくつかの機能を決定する(私はこの家族と呼ぶだろう)。あなたが行くことができる。この場合

class EnclosureFamily { 
    public: 
     double compute_volume_in_room() = 0; // abstract; 
}; 
class Enclosure 
{  
    public:   //some common function 
     double compute_volume_in_room() { 
      return f->compute_volume_in_room(); // forwarding 
     } 
    protected: 
     int m_boxHeight; 
     speaker *m_speakerBass; 
     EnclosureFamily *f; // ok, but smart ponters should be preferred 
}; 
class BoxEnclosure : public EnclosureFamily { 
    public: 
     double compute_volume_in_room() { ... }; 
}; 

これは、あなたが望むとおりにエンクロージャファミリを変更することができます。ところで、これはstrategy patternの実装です。私はその道を進んで助言しませんしかし

*static_cast<Enclosure*>(BassReflex2Simu)= initialBox; // not forbidden but slicing 

(中保つ:あなたが本当にあなたのオリジナルのデザインを維持する必要がある場合は

、あなたは親にキャストし、スライス効果を利用し使用して、親クラスを上書きする可能性が親に3のルールを正しく実装する必要があることに気をつけてください)

+0

これは可能ですが汎用性はありません。私は各サブクラスに一般的なパラメータしたがって、ある日、親に一般的なパラメータを追加すると、すべての子クラスを手動で更新する必要があります。ありがとうございました ! – Boulgour

関連する問題