2012-02-11 12 views
3

私は以下の特定のシナリオを持っています。下のコードはBとCクラスの 'say()'関数を出力し、 'Bは..'と 'C says ...'を出力しますが、それはありません。すべてのアイデア.. 私も多相性を学んでいます下記のコード行に関連するいくつかの質問をコメントしました。多型オブジェクトのリスト

class A 
{ 
public: 
// A() {} 
    virtual void say() { std::cout << "Said IT ! " << std::endl; } 
    virtual ~A(); //why virtual destructor ? 
}; 

void methodCall() // does it matters if the inherited class from A is in this method 
{ 
    class B : public A{ 
    public: 
     // virtual ~B(); //significance of virtual destructor in 'child' class 
     virtual void say() { // does the overrided method also has to be have the keyword 'virtual' 
      cout << "B Sayssss.... " << endl; 
     } 
    }; 
    class C : public A { 
    public: 
     //virtual ~C(); 
     virtual void say() { cout << "C Says " << endl; } 
    }; 

    list<A> listOfAs; 
    list<A>::iterator it; 

    # 1st scenario 
    B bObj; 
    C cObj; 
    A *aB = &bObj; 
    A *aC = &cObj; 

    # 2nd scenario 
    // A aA; 
    // B *Ba = &aA; 
    // C *Ca = &aA; // I am declaring the objects as in 1st scenario but how about 2nd scenario, is this suppose to work too? 

    listOfAs.insert(it,*aB); 
    listOfAs.insert(it,*aC); 

    for (it=listOfAs.begin(); it!=listOfAs.end(); it++) 
    { 
     cout << *it.say() << endl; 
    } 
} 

int main() 
{ 
    methodCall(); 
    return 0; 
} 

答えて

2

あなたの問題は、をスライスして、あなたがこの質問を確認してくださいと呼ばれている:あなたが他の場所で、実際のオブジェクトを格納する必要があるため、寿命管理が非自明と最高なunique_ptrとして専用のラッパーに残っているLearning C++: polymorphism and slicing

あなたはA Sへのポインタのリストとしてこのリストを宣言する必要があります。

list<A*> listOfAs; 

し、これらを挿入とaCポインタを指すオブジェクトのコピーを作成するのではなく、ポインタを指します。あなたがリストに要素を挿入する方法が間違っている、あなたではなく挿入するためのpush_back機能を使用する必要があります。

B bObj; 
C cObj; 
A *aB = &bObj; 
A *aC = &cObj; 

listOfAs.push_back(aB); 
listOfAs.push_back(aC); 

を次に、あなたのループは次のようになります。

list<A*>::iterator it; 
for (it = listOfAs.begin(); it != listOfAs.end(); it++) 
{ 
    (*it)->say(); 
} 

出力:

B Sayssss.... 
C Says 

お役に立てれば。

+0

実際には、*裸のポインタのコンテナを使用することは、パンドラのワープ・ネストですが、いくつでも問題が起こる可能性があります。 –

+0

私は同意します。しかし、この場合は、裸のポインタを使用する方が適切であると考えて、そこで何が起こっているのかをよく理解するようにします。上記のシナリオで – LihO

+0

私はまた私がそれを使用したらリスト要素の世話をする必要があります..私はそれか何かを削除する必要がありますか? – LivingThing

1

仮想クラス階層の多型がベースのみのサブオブジェクトに参照またはポインタを介して動作:それはBaseで仮想関数の場合

struct Der : Base { /* ... */ }; 

Der x; 

Base & a = x; 

a.foo(); // calls Der::foo() from x 

機能fooが多形派遣されます。多形性とは、タイプBaseのオブジェクトのメンバ関数を呼び出している間に、実際に呼び出される関数がクラスDerに実装されている可能性があるということです。

コンテナには固定タイプの要素しか格納できません。多相コレクションを格納するために、代わりに基本クラスへのポインタのコンテナを持つことができます。

#include <list> 
#include <memory> 


int main() 
{ 
    std::list<std::unique_ptr<Base>> mylist; 

    mylist.emplace_back(new Der1); 
    mylist.emplace_back(new Der2); 
    // ... 

    for (p : mylist) { p->foo(); /* dispatched dynamically */ } 
} 
+0

1:このコンテナは固定タイプの要素のみを格納できます。手段 ?? 2: "代わりに基本クラスへのポインタのコンテナを持つことができます" ' listOfAs;の代わりに' listOfAs list 'を意味しますか? – LivingThing

0

list::iterator it; B bObj; C cObj; A *aB = &bObj; A *aC = &cObj; listOfAs.insert(it,*aB);

あなたは "それ" を初期化する必要はありませんか? 私はあなたがそれを行うべきだと思う= listOfAs.begin();挿入を開始する前に