Thomas
Thomas

Reputation: 673

Attribute's type change with inheritance in C++

I have a class A, working on a specific kind of objects (instances of A there). I'd like to have a class B, which has mostly (i.e. not all its methods are the same) the same behavior, but which is working on a different class of objects (B there).

Here is what I tried:

#include <iostream>
#include <vector>

class A
{
public:
    virtual void perform() { data.push_back(A()); };
    std::vector<A> data;
};


class B : protected A
{
public:
    B() : A() {}
    void test() { perform(); }
    std::vector<B> data;
};


int main()
{
    B b;
    b.test();
    std::cout << b.data.size() << std::endl;
}


// output: 0
// I expected: 1

I was expecting std::vector<B> to be used during the insertion instead of std::vector<A>, as B is a subclass of B.

What am I missing? Is there a way I can make sure every method defined in class A work as expected in class B?

Thanks!

Upvotes: 0

Views: 541

Answers (2)

chrisaycock
chrisaycock

Reputation: 37928

Inheritance-based polymorphism in C++ only deals with functions, not data elements. That is, changing the object's type only affects which function is called, not which data element is used.

Also, you cannot assign an object of type A to a container of B's. Ignoring polymorphism, you can't do:

std::vector<B> data;
data.push_back(A());

That's because B inherits from A, not the other way around.

Third, the assignment would have to use pointers anyway, not outright objects. So you'd have to do something like:

std::vector<A*> data;
data.push_back(new B);

Upvotes: 3

dario_ramos
dario_ramos

Reputation: 7309

When you need the same behavior for different types, use a template:

template <typename Element>
class Container
{
public:
    void perform() { data.push_back(Element()); };
    std::vector<Element> data;
};

int main(){
    Container<A> a;
    Container<B> b;
    a.perform();
    b.perform();
    std::cout << a.data.size() << std::endl;
    std::cout << b.data.size() << std::endl;
}

Disclaimer: not compile tested

Upvotes: 0

Related Questions