Question

Possible Duplicate:
Overriding parent class’s function

I'm struggling with calling a virtual function in C++.

I'm not experienced in C++, I mainly use C# and Java so I might have some delusions, but bear with me.

I have to write a program where I have to avoid dynamic memory allocation if possible. I have made a class called List:

template <class T> class List {
public:
    T items[maxListLength];
    int length;


    List() {
        length = 0;
    }

    T get(int i) const {
        if (i >= 0 && i < length) {
            return items[i];
        } else {
            throw "Out of range!";
        }
    };

    // set the value of an already existing element
    void set(int i, T p) {
        if (i >= 0 && i < length) {
            items[i] = p;
        } else {
            throw "Out of range!";
        }
    }

    // returns the index of the element
    int add(T p) {
        if (length >= maxListLength) {
            throw "Too many points!";
        }
        items[length] = p;
        return length++;
    }

    // removes and returns the last element;
    T pop() {
        if (length > 0) {
            return items[--length];
        } else {
            throw "There is no element to remove!";
        }
    }
};

It just makes an array of the given type, and manages the length of it.

There is no need for dynamic memory allocation, I can just write:

List<Object> objects;
MyObject obj;
objects.add(obj);

MyObject inherits form Object. Object has a virtual function which is supposed to be overridden in MyObject:

struct Object {
    virtual float method(const Input& input) {
        return 0.0f;
    }
};

struct MyObject: public Object {
    virtual float method(const Input& input) {
        return 1.0f;
    }
};

I get the elements as:

objects.get(0).method(asdf);

The problem is that even though the first element is a MyObject, the Object's method function is called. I'm guessing there is something wrong with storing the object in an array of Objects without dynamically allocating memory for the MyObject, but I'm not sure.

Is there a way to call MyObject's method function? How? It's supposed to be a heterogeneous collection btw, so that's why the inheritance is there in the first place.

If there is no way to call the MyObject's method function, then how should I make my list in the first place?

Also I have no access to libraries outside of math.h and stdlib.h, so vector is not available for example.

Was it helpful?

Solution 2

When you do this:

objects.add(obj);

you are adding a copy of the Object part of the MyObject to the list, so it is no longer a MyObject.

You might be tempted to try doing this:

int add(T const &p) {
    if (length >= maxListLength) {
        throw "Too many points!";
    }
    items[length] = p; // now the problem is here
    return length++;
}

but now the copy of the Object part of p happens during the assignment.

To make the list be heterogeneous, it is going to have to be a list of pointers, but you also wanted to avoid dynamic memory allocation. You can avoid dynamic memory allocation if you are careful:

 Object obj1;
 MyObject obj2;
 List<Object*> object_ptrs;
 object_ptrs.add(&obj1);
 object_ptrs.add(&obj2);
 object_ptr.get(1)->method(input);
 object_ptr.get(0)->method(input);

but again, you have to be very careful. The list is now pointing to the two objects on the stack. If you return from this function, those two objects will be destroyed. Note that I've purposefully put the list of object pointers after the objects, so that the list will get destroyed before the objects, so the list won't be left pointing to garbage. However, if you return a copy of the list, you would still have a problem.

OTHER TIPS

You need to store pointers in the list. Try this:

List<Object*> objects;
Object *obj1 = new Object;
MyObject *obj2 = new MyObject;
Object *obj3 = new MyObject;

objects.add(obj1);
objects.add(obj2);
objects.add(obj3);

// This calls the implementation in Object class
objects.get(0)->method(asdf);

// This calls the implementation in MyObject class
objects.get(1)->method(asdf);

// This calls the implementation in MyObject class
// Polymorphism here
objects.get(2)->method(asdf);

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top