I am trying to add a number of subclassed elements into a vector, iterate through them calling a overridden method and want it to call the overridden method where possible. However I have found that it appears to only be calling the superclass method.
I learnt Java and am unsure why it is doing this in C++. I have tried rewriting the code using a vector of pointers of the superclass and casting the pointer of the subclass to the superclass. Accessing this through pointers then works.
Ideally I dont want to have to put a list of pointers into the vector since then I have to manually delete each one (I believe?) to stop memory leaks since I will be creating the objects with new so they persist past the method call to add them into the vector.
Is there a better way to do this or am I stuck to using pointers and calling delete on the created objects when the parent class is unneeded? Preferably the vector would be a list of class X rather than a list of pointers of class X
My structure is:
class a { vector vec of class X,
method to create and add an instance of X into vector vec,
method to create and add an instance of Y into vector vec }
class X { talk() }
class Y : public X { talk() }
Code to demonstrate what I ideally want to do, but showing its broken by only calling the superclass method:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
class A {
public:
virtual void talk() { printf("A\n"); }
};
class B: public A {
public:
void talk() { printf("B\n"); }
};
int main(void) {
std::vector<A> vec;
std::vector<A*> vec2;
A a;
B b;
a.talk();
b.talk();
vec.push_back(a);
vec.push_back(b);
vec2.push_back(&a);
vec2.push_back(&b);
for(int i = 0; i < vec.size(); i++) {
vec[i].talk();
vec2[i]->talk(); //bad but short for example
}
}
To get the polymorphic behaviour you want you need to add the virtual
specifier to the functions in the base class that you want to override in derived classes.
class A {
public:
virtual void talk() { printf("A\n"); }
};
You should also make a habit of adding the override
specifier on overridden functions in derived classes so that the compiler can help you with these kind of issues.
class B: public A {
public:
virtual void talk() override { printf("B\n"); }
// ^ Compiler will report an error if base class' function
// is not virtual.
};
Also you can not assign a derived object to an instance of a base class, or slicing will occur.
std::vector<A> vec;
/* ... */
B b;
/* ... */
vec.push_back(b); // Slicing. Information only in B is lost.
Live example using virtual
specifier
Live example without virtual
specifier
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With