list of polymorphic objects

后端 未结 3 805
星月不相逢
星月不相逢 2020-12-03 19:09

I have a particular scenario below. The code below should print \'say()\' function of B and C class and print \'B says..\' and \'C says...\' but it doesn\'t .Any ideas.. I a

相关标签:
3条回答
  • 2020-12-03 19:57

    Your problem is called slicing and you should check this question: Learning C++: polymorphism and slicing

    You should declare this list as a list of pointers to As:

    list<A*> listOfAs;
    

    and then insert these aB and aC pointers to it instead of creating copies of objects they are pointing to. The way you insert elements into list is wrong, you should rather use push_back function for inserting:

    B bObj; 
    C cObj;
    A *aB = &bObj;
    A *aC = &cObj;
    
    listOfAs.push_back(aB);
    listOfAs.push_back(aC);
    

    Then your loop could look like this:

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

    Output:

    B Sayssss....
    C Says
    

    Hope this helps.

    0 讨论(0)
  • 2020-12-03 19:58

    Polymorphism of virtual class hierarchies only works through references or pointers to a base subobject:

    struct Der : Base { /* ... */ };
    
    Der x;
    
    Base & a = x;
    
    a.foo();   // calls Der::foo() from x
    

    The function foo is dispatched polymorphically if it is a virtual function in Base; the polymorphism refers to the fact that while you are calling a member function of an object of type Base, the function that actually gets called may be implemented in the class Der.

    Containers can only store elements of a fixed type. In order to store a polymorphic collection, you could instead have a container of pointers to the base class. Since you need to store the actual objects elsewhere, lifetime management is non-trivial and best left to a dedicated wrapper such as unique_ptr:

    #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 讨论(0)
  • 2020-12-03 20:03

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

    Do you not need to initialize "it" ? I believe you should do it = listOfAs.begin(); before starting to insert.

    0 讨论(0)
提交回复
热议问题