TheDarkestSegFault
TheDarkestSegFault

Reputation: 13

Pointers to vectors of derived a derived class

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

Answers (2)

user5506728
user5506728

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

sh-
sh-

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

Related Questions