Saturday, March 31, 2012

Polymorphic Queue Problems

And now this doesn't work. I assume I'm going to have to do something involving "new" and "delete"...


 #include <iostream>  
 #include <queue>  
 using namespace std;  
 class thing1  
 {  
 public:  
   virtual void thingTest()  
   {  
     cout << "I AM THING 1\n";  
   }  
 };  
 class thing2: public thing1  
 {  
 public:  
    void thingTest()  
   {  
     cout << "I AM THING 2\n";  
   }  
 };  
 void DoMoreStuff( thing1& temp )  
 {  
      temp.thingTest();  
 }  
 queue <thing1> QueueThingy;  
 int main()  
 {  
      QueueThingy.push( thing2() );  
      QueueThingy.push( thing1() );  
      QueueThingy.push( thing2() );  
      QueueThingy.push( thing1() );  
      QueueThingy.push( thing2() );  
      while( QueueThingy.size() )  
      {  
           QueueThingy.front().thingTest();  
           QueueThingy.pop();  
      }  
 }  

Expected:
I AM THING 2
I AM THING 1
I AM THING 2
I AM THING 1
I AM THING 2

Actual:
I AM THING 1
I AM THING 1
I AM THING 1
I AM THING 1
I AM THING 1

Edit (thanks Matt):
Now I get expected... but I'm not TOTALLY convinced this doesn't cause a memory leak...

 #include <iostream>  
 #include <queue>  
 using namespace std;  
 class thing1  
 {  
 public:  
   virtual void thingTest()  
   {  
     cout << "I AM THING 1\n";  
   }  
 };  
 class thing2: public thing1  
 {  
 public:  
    void thingTest()  
   {  
     cout << "I AM THING 2\n";  
   }  
 };  
 void DoMoreStuff( thing1& temp )  
 {  
      temp.thingTest();  
 }  
 queue <thing1 * > QueueThingy;  
 void main()  
 {  
      QueueThingy.push( new thing2() );  
      QueueThingy.push( new thing1() );  
      QueueThingy.push( new thing2() );  
      QueueThingy.push( new thing1() );  
      QueueThingy.push( new thing2() );  
      while( QueueThingy.size() )  
      {  
           QueueThingy.front()->thingTest();  
           delete QueueThingy.front();  
           QueueThingy.pop();  
      }  
 }  

2 comments:

  1. to use polymorphism with the STL, you generally have to store pointers in the container... i.e. change QueueThingy to a std::queue<thing1 *> and change the rest of the code accordingly...

    QueueThingy.push( new thing2() );

    Then the loop becomes something like
    QueueThingy.front()->thingTest();
    delete QueueThingy.front();
    QueueThingy.pop();

    ReplyDelete
  2. thank you matt, added edit. still not convinced it doesn't have a memory leak though...

    ReplyDelete