List of polymorphic objects

I have a specific scenario below. The code below should print the "say ()" function of class B and C and print "B says .." and "C says ...", but that is not the case. All ideas .. I study polymorphism, so I also commented on a few related questions in the lines of code below.

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; } 
+3
c ++ list polymorphism stl virtual-functions
source share
3 answers

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

You should declare this list as a list of pointers to A s:

 list<A*> listOfAs; 

then paste these aB and aC pointers into them instead of making copies of the objects they point to. The way you insert items into the list is wrong, you must use the push_back function to insert:

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

Then your loop might 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.

+2
source share

Polymorphism of virtual class hierarchies works only with the help of links or pointers in the base subobject:

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

The function foo sent polymorphically if it is a virtual function in Base ; polymorphism refers to the fact that when calling a member function of an object of type Base function that is actually called can be implemented in the Der class.

Containers can only store items of a fixed type. To save a polymorphic collection, you can instead have a container of pointers to the base class. Since you need to store the actual objects elsewhere, lifecycle management is non-trivial and best left to a dedicated shell 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 */ } } 
+1
source share

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

You do not need to initialize "this"? I believe you should do this = listOfAs.begin (); before starting the insertion.

0
source share

All Articles