Reputation: 13
I'm trying to have a vector of pointers to vectors of differents classes and where each classes is derived from a same base class.
My code:
#include <iostream>
#include <vector>
#include <stdlib.h>
class A
{
public:
A() { std::cout << "A constructor.\n"; }
virtual ~A() { std::cout << "A destructor\n"; }
virtual void iAm() { std::cout << "I am A.\n"; }
};
class B : public A
{
public:
B() { std::cout << "B constructor.\n"; }
~B() { std::cout << "B destructor.\n"; }
virtual void iAm() { std::cout << "I am B.\n"; }
private:
std::string s;
};
class C : public A
{
public:
C() { std::cout << "C constructor.\n"; }
~C() { std::cout << "C destructor.\n"; }
virtual void iAm() { std::cout << "I am C.\n"; }
private:
std::string s;
int n;
};
int main()
{
std::vector<std::vector<A>*> vect;
vect.resize(3);
vect[0]=new std::vector<A>;
vect[1]=(std::vector<A>*) new std::vector<B>;
vect[2]=(std::vector<A>*) new std::vector<C>;
vect[0]->push_back(A());
vect[0]->push_back(A());
vect[1]->push_back(B(methods are A methods));
vect[1]->push_back(B());
vect[2]->push_back(C());
vect[2]->push_back(C());
(*vect[0])[0].iAm();
(*vect[0])[1].iAm();
(*vect[1])[0].iAm();
(*vect[1])[1].iAm();
(*vect[2])[0].iAm();
(*vect[2])[1].iAm();
}
But the execution give me:
A constructor.
A destructor.
A constructor.
A destructor.
A destructor.
A constructor.
B constructor.
B destructor.
A destructor.
A constructor.
B constructor.
A destructor.
B destructor.
A destructor.
A constructor.
C constructor.
C destructor.
A destructor.
A constructor.
C constructor.
A destructor.
C destructor.
A destructor.
I am A.
I am A.
I am A.
I am A.
I am A.
I am A.
I don't understand why, although I create B
and C
objects, the call of the method iAm()
call the A's
iAm()
. The call of B
and C
iAm()
must call the versions of B
and C
because the constructor are B
and C
and because I just cast pointers to the vectors, not the elements in the vector.
What I didn't understand about this?
Thanks You.
Upvotes: 1
Views: 128
Reputation:
You might want to check out this question: Vector that can have 3 different data types C++
Here's an example how your code could work:
std::vector<std::vector<A*>*> vect;
//you can also do vect.resize(3) and then write something like vect[0] = new std::vector<A*>;
vect.push_back(new std::vector<A*>);
vect[0]->push_back(new A());
vect.push_back(new vector<A*>);
vect[1]->push_back(new B());
(*vect[0])[0]->iAm();
(*vect[1])[0]->iAm();
This will print:
A constructor.
A constructor.
B constructor.
"I am A."
"I am B."
Also, consider using smart pointers.
Upvotes: 1
Reputation: 1031
Your mistake is that you assume that std::vector<B>
is compatible with std::vector<A>
because B is derived from A. This is not the case. The inheritance relationship between A and B does not translate to an inheritance relationship between std::vector<A>
and std::vector<B>
. You had to use C-style casts to silence the compiler's error messages, but that doesn't fix the problem.
Upvotes: 4