2012-05-06 14 views
1

2つのクラスAとBがあるとします。どちらもスーパークラスCのサブクラスです。次に、CがメソッドareYouA()を定義していると仮定しましょう。オブジェクトがAクラスのオブジェクトであるかどうかを確認するメソッドです。これは、オブジェクト指向のアプローチで抽象クラスを使用する正しいアプローチですか?

だから、可能なコード、Cの++で、次のようになります。

C object1 = A() 

C object2 = B() 

if (object1.areYouA()==true){//crazy code here regarding if it's an A object} 

if (object2.areYouA()==false){//crazy code here regarding if it's a B object} 

OOのPOVから、彼らはでている場合、それぞれのオブジェクトを求めるためにBとCのクラスにメソッドを追加することが適切ですクラス???それが正しくない場合は、これに別の方法がありますか?私の目的は明らかです。私は必要な2つのクラスAとBを持っています。ある時点では、AクラスまたはBクラスのバイナリデータの部分があります。それは構造が変化する必要があり、その一部がBのクラスのオブジェクトになります。だから私のアプローチは、抽象クラスを親として考え、最初はCオブジェクトを宣言してAオブジェクトを格納し、後でBオブジェクトを変更して格納することでした。 パターンのようにこれに別の承認がありますか?

ADDITIONAL INFO:

私はこのことについて非常に明確波平と思います。ファイル1のAオブジェクトからの情報とファイル2のBオブジェクトからの情報を保存したいとしましょう。そのマザークラスをインタフェースとして使用する場合、それぞれのファイルに格納するAオブジェクトかBオブジェクトかどうかをどのように判断できますか?私はそれらのファイル名のために各オブジェクトに属性を追加する必要がありますか?つまり、ファイルの名前を変更する必要がある場合は、すべてのオブジェクトも変更する必要があります。

+5

あなたのコードはコンパイルされず、たとえそれがあったとしても、あなたの考えをしません。多相性は、参照とポインタを通してのみ機能し、コピーでは機能しません(「スライス」を参照)。 –

答えて

1

これは私の意見では設計上の問題です。あなたの問題をよりよく分析する必要があります。なぜあなたのオブジェクトの種類を知る必要がありますか?なぜあなたはAとBのクラスにバイナリデータで必要なことをするのでしょうかインターフェイスメソッドを実装していないのですか?このように実装する方法のイメージを得るために訪問者のデザインパターンを見てください。

void process_data(C & x) // <-- Note: take argument by reference!! 
{ 
    x.do_crazy_stuff(); 
} 

これは、タイプの任意のオブジェクト上で動作します:

struct C 
{ 
    virtual void do_crazy_stuff() { } // (see text below) 
    virtual ~C() { }     // always have a virtual d'tor for polymorphic bases 
}; 

struct A : C 
{ 
    virtual void do_crazy_stuff() { /* your crazy code for A */ } 
}; 

struct B : C 
{ 
    virtual void do_crazy_stuff() { /* your crazy code for B */ } 
}; 

は今、あなたはどこでも同じインタフェースを使用することができます。

+1

ビジターパターンは恐ろしい過度のものであり、現在の状況ではかなり間違っていると思われます。 –

+0

パターンを指してくれてありがとう、多形性のためにインターフェースを使う必要があるかもしれないという事実をありがとう。私はこの問題が完全に解決するかどうかを調べるために私の問題をさらに調べます。 – Ale

+0

@KerrekSBそれは問題の種類によって異なります。私はちょうどよく文書化された例として設計パターンを言及しました。 – AlexTheo

4

正しい方法は、多型の動作を実装するためにを仮想関数を使用することですC

int main() 
{ 
    A x; 
    B y; 
    process_data(x); // calls x.A::do_crazy_stuff 
    process_data(y); // calls x.B::do_crazy_stuff 
} 

好きなら、基本機能を純粋仮想として宣言することもできます。これにより、基本クラスが抽象的なになります(インスタンス化することはできません)。

+0

多形性を思い出させてくれてありがとう、そして私はこれを使うことができなかったことを知らなかった: C object1 = A() – Ale

4

まず第一に、

C object1 = A(); 
C object2 = B(); 

スライスオブジェクト。それらはタイプAまたはBでなく、Cです。

あなたはこのために、ポインタを使用することができます。

C* object1 = new A(); 
C* object2 = new B(); 

ポインタCが、それらはそれぞれABのインスタンスを指します。

第2に、あなたのアプローチは間違っています。あなたは多形性を利用していないようです。クラス間で共有される機能がある場合は、Cに実装する必要があります。変更された場合は、virtualメソッドが必要です。

オブジェクトの種類に関する知識は、通常少なくともコードの匂いです。多態性を使用するだけで動作を変更できます。それが本当に必要な場合、正しい方法はdynamic_castを使用しないものもありますが:

​​

pAobject1はタイプAのオブジェクトを指していない場合NULLになります。

+0

初期段階の誰かにポインタと 'new'を使うのが少し悪魔ですC++を学ぶ –

+1

また、ポインタとnewを提案しているなら、 'std :: unique_ptr'や' std :: shared_ptr'のようなスマートポインタも少なくともいくつか示唆しています。 – Nawaz

+0

私は公式のC++チュートリアルを読んでいます。新しいものやポインタの使用については、すべてここにありますが、慣れておく必要があります。あなたの配慮をお寄せいただきありがとうございます。 – Ale

関連する問題