Overridden method doesn't get invoked

H

Hermann Lichte

Hi,

I've naively written a piece of code that's not doing what I want it to.
I want to store objects in a vector of some base class A. This base
class provides a method doSomething() that is overridden in subclasses.
When I invoke doSomething() I always end up with the implementation
provided by the base class A, regardless the subclass I used for
instantiating the object. I suppose that this is related to the fact
that the vector holds references and not pointers, but that's what it
has to offer. How can I make it work? I've got some example code here
to illustrate my problem.

#include <iostream>
#include <vector>

using namespace std;

class A {
public:
A();
virtual ~A();
virtual double doSomething(int parameter);
};

A::A()
{
}

A::~A()
{
}

double A::doSomething(int parameter)
{
cout << "A: " << parameter << "\n";
return 0.0;
}

class B : public A {
public:
B();
virtual ~B();
virtual double doSomething(int parameter);
};

B::B()
{
}

B::~B()
{
}

double B::doSomething(int parameter)
{
cout << "B: " << parameter << "\n";
return 0.0;
}

class C
{
vector<A> Items;
public:
C();
~C();
void addItem(A& item);
A* getItem(int index);
};

C::C() : Items()
{
}

C::~C()
{
}

void C::addItem(A& item)
{
Items.push_back(item);
}

A* C::getItem(int index)
{
return &Items.at(index);
}

int main()
{
C storage;
B* object = new B();
storage.addItem(*object);
A* another = storage.getItem(0);
A* another2 = object;
another->doSomething(123); // doesn't call B::doSomething()
// but that's what I want
another2->doSomething(123); // does call B::doSomething()
delete object;
return 0;
}

Any advice is appreciated.

Kind regards,
Hermann
 
K

Kai-Uwe Bux

Hermann said:
Hi,

I've naively written a piece of code that's not doing what I want it to.
I want to store objects in a vector of some base class A. This base
class provides a method doSomething() that is overridden in subclasses.
When I invoke doSomething() I always end up with the implementation
provided by the base class A, regardless the subclass I used for
instantiating the object. I suppose that this is related to the fact
that the vector holds references and not pointers, but that's what it
has to offer.

The vector does not hold references, it holds actual objects of type A.

How can I make it work?

You have at least the following options:

a) Use std::vector<A*> instead of std::vector<A>. In this case, you need to
take care of memory management on your own.

b) Use std::vector< tr1::shared_ptr<A> >. In this case, memory management
will be taken care of.

c) Use std::vector< copy_ptr<A> > or std::vector< clone_ptr<A> >. These
smart pointers have been discussed in the archives. They provide deep copy
semantics.

d) Use a specialized container for pointers. I understand that several are
available from various libraries.

[snip: code illustrating slicing]


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,981
Messages
2,570,187
Members
46,729
Latest member
ScarlettJe

Latest Threads

Top