views:

47

answers:

1

In hope to simplify a homework problem dealing with inheritance, I thought it might be better to use polymorphism to accomplish the task. It isn't required, but makes much more sense if possible. I am, however, getting symbol errors making it work as I thought it should or just the base class definition is called. I want the overloaded function based on the object to be called.

template <class T>
class Fruit {
  private:
    int count;
    T type;
  public:
    virtual void Info();
};

template <class T>
class Apple : public Fruit<T> {
  private:
    int variety;
  public:
    void Info();
};

// more fruit-child classes

vector<Fruit<int> > fruits; // contains object of various derived types

...

for(int i=0; i<fruits.size(); i++
    fruits[i].Info();
+1  A: 

I'm going to leave the type thing aside, though I think you probably don't need it and therefore don't need the template... but, here's what you need:

First, the vector should be of pointers:

vector<Fruit<int> *> fruits;

this prevents slicing (where the Apple part of the object is cut off).

Also, now that you have pointers, your loop will change:

for(int i=0; i<fruits.size(); i++)
    fruits[i]->Info();

This will now call the appropriate Info function for the type of fruit you have.

JoshD
I would use vector< shared_ptr< Fruit< int > > > instead of raw pointers.
VJo
@VJo: That would be best, but I'm assuming for this assignment that won't be allowed. Also, given the OP's question, I'm assuming that OP would benefit from learning this method.
JoshD
This gives compile issues `vector<Fruit<int> *> fruits; Apple<int> a; fruits.push_back(a);` Thanks for the help so far, this is definitely in the direction I need...
mike_b
@mike_b: Since the vector is of pointers, you'll need to push the address of the apple: `fruits.push_back(`. But since you created the apple on the stack, it'll be destroyed before you want it to be. That's why you need to create it on the heap with `new`: `Apple<int> *a = new Apple<int>;` Then you push the pointer a: `fruits.push_back(a);`
JoshD
Without leaving things allocated, can I say create a pointer `Apple<int> *a` and then as needed, create new heap allocations such as `for(int i=0;i<10;i++){a=new Apple<int>; fruits.push_back(a);}`? Then to cleanup, I would need to do say `Apple<int> *temp; temp=fruits.back(); fruits.pop_back(); delete temp;` to de-allocate the memory from the heap?
mike_b
@mike_b: YES! That's exactly right, and works wonderfully. Well done. If you wanna get crazy, you can cut it down to `fruits.push_back(new Apple<int>)` Cleanup is just fine how it is.
JoshD
Thanks a lot. I just need to adapt this, but it definitely works now as I hoped.
mike_b