私はしばらくこの設計問題に苦労しました。私は何をしようとしているのかを説明するために最善を尽くし、様々なものが私が見たもの、私が何をしようとしているのか、そしてなぜそれに近づいたのです。C++で多重継承と複合クラスを含むデザインを解決する
私は同じ種類のオブジェクトを繰り返し処理する科学計算環境で働いています。太陽系を含む銀河を想像してみましょう。各太陽系には惑星系が含まれ、各惑星系には月が含まれています。この目的のために私は状況が「ある」状況であると考え、私は太陽系へのアクセスを銀河に与えるために構成を使用し、各太陽系は月にアクセスできる惑星系へのアクセスを取ったそれ自身のクラスです。
私が取り組んでいるさまざまな問題には、これらのオブジェクトに関するさまざまな種類のデータが含まれていることがよくあります。また、さまざまな種類のデータが利用できるようになると、私は自分のオブジェクトで特定のことを行うことができます。だから、私は私に利用可能なデータタイプ1を持っているとき、私は次のクラス
class GalaxyOne { /* … */ };
class SolarSystemOne { /* … */ };
class PlanetOne{ /* … */ };
class MoonOne{ /* … */ };
を作成し、私は私に利用可能なデータタイプ2を持っているとき、私は、各クラスの複合側面が配られる
class GalaxyTwo { /* … */ };
class SolarSystemTwo { /* … */ };
class PlanetTwo{ /* … */ };
class MoonTwo{ /* … */ };
を作成含まれるクラスへのポインタを含むベクトルなどのコンテナ変数を使用してたとえば、各ギャラクシークラス内では、1つが見つかります。
class GalaxyTwo{ /* … */
protected:
std::vector<SolarSystemTwo*> solarSystems;
/* … */
};
私がクラスを高次クラスに結合するのは難しいです。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo{
/* Additional methods */
};
GalaxyOneTwoがGalaxyOneとGalaxyTwoから、それのバージョンを持っているでしょうしかし、これはsolarSystemsベクトルにおける曖昧さの問題を作成します。さらに、継承するベクトルには、必要とされるタイプのSolarSystemOneTwoではないオブジェクトへのポインタが含まれています。ですから、すべてのオブジェクトがすべてのコンテナ変数を置いた場所から継承するテンプレートクラスを作成できると思いました。
template<MoonT,PlanetT,SolarSystemT>
class PrimitiveGalaxy {
private:
std::vector<SolarSystemT*> solarSystems
};
class GalaxyOne: public PrimitiveGalaxy <MoonOne,PlanetOne,SolarSystemOne>{
/* No longer defining any container variables for composition */
};
このアプローチは、これらの基本的な銀河の種類(GalaxyOneとGalaxyTwo)のために非常にうまく動作します。しかし、結合した銀河タイプを作成しようとすると、私はあらゆる種類のあいまいさを感じます。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo, public PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>{
/* … */
};
それは一度GalaxyOneとGalaxyTwoからそれぞれ継承バージョンとGalaxyOneTwo介して第三の時間を通して、三回定義されているので、私はGalaxyOneTwoで定義されたメソッド内solarSystemsを使用する場合、私はあいまいさを得ます。
私は特定のものと
PrimitiveGalaxy :: solarSystems
適切なベクトルを参照するために、それぞれの時間を使って、この曖昧さを取り除くことができますが、それは余分なタイピングの多くを必要とするため、これは望ましいことではありませんおよび構文。
私は各銀河タイプと原始銀河の間に友情を使うことを考えましたが、これには同様のレベルの冗長な書き込みが必要です。
私は名前空間は、コードの私の文章を簡素化することが予感を持っていますが、私はそのようなことを名前空間を定義する方法を確認していないsolarSystemsへの参照が PrimitiveGalaxy :: solarSystems
への参照であることをGalaxyOneTwoのために定義された名前空間内の編集:
GalaxyOneとGalaxyTwoの唯一の違いは、solarSystemsに含まれるクラスの種類ではありません。各クラスは銀河に関連するさまざまなデータを扱うため、多くの違いがあります。したがって、これらの状態変数と、データを計算して印刷するメソッドに対して、異なる状態変数、ゲッター、およびセッターを持つ異なるクラスを作成します。 solarSystemsは私にこのように問題を与えている特徴の例です。これは私がここで述べたものです。 GalaxyOneTwoが作成されると、GalaxyOneとGalaxyTwoで使用されているのと同じデータが使用されるため、すべての変数とメソッドを継承したいと考えています。また、データをさまざまな方法で組み合わせることができるため、GalaxyOneTwo内で新しいメソッドを作成する必要があります。これらは相続を利用する多くの相違の一部です。それは言われている、それは私に問題を与える構成を可能にするコンテナ変数です。各solarSystemクラスの中には、惑星へのアクセスなどを与える同様のベクトルがあります。
編集:
ここで、一般的に私のデザイン哲学に特に専用の質問については(私の現在の設計の試みを解決しようとする上で、この質問の強調ではなく)次のリンクを参照してください。 Guidance in creating design for multiple-inheritance composite classes in c++
GalaxyOneとは何ですか?銀河の異なる種類の銀河のコレクション、または2つの共通のインターフェイス(または実装???)? GalaxyOneTwoでどんな操作をしたいですか? –
私が上記で説明したように、GalaxyOneTwoはGalaxyOneとGalaxyTwoのメンバー機能にアクセスできるだけでなく、同じデータを処理できる銀河です。伝統的に利用可能なさまざまな種類のデータより複雑なデータ分析を行うためにGalaxyOneとGalaxyTwoにのみ適用されます。 – PhiloEpisteme
いいえ、私は疑問に思っています:あなたは継承を使ってモデル化しようとしていることは何ですか?銀河系と銀河系の2つに見られる太陽系のすべての種類を持つ銀河の一種?どのような操作を求めたら、私は銀河の総質量、光度、星数などを得る具体的な例を意味します。 GalaxyOneTwoがどのような複合機能を持つべきかの例を挙げると、より良い回答が得られるかもしれません。 –