2
votes

I understand that smart pointers make it possible to store objects of different class (but derived from the same base class) in a vector. I am having trouble getting this to work. A simple example;

class Base
{
public:
    virtual void disp() { printf("Base class\n"); }
};

class Derived : Base
{
public:
    virtual void disp() { printf("Derived class\n"); }
};

static void test()
{
    std::vector< std::shared_ptr<Base> > v;
    std::shared_ptr<Base> pa( new Base() );
    std::shared_ptr<Derived> pb( new Derived() );
    v.push_back(pa);
    v.push_back(pb);   // compile error wants, std::shared<Base> not Derived
    v[0]->disp();
    v[1]->disp();
}

My background with simple, "C with classes" type C++ tells me that a pointer to Derived is also a pointer to Base, but apparently this logic doesn't transfer to smart pointers. How do I fix this ? Any pointers on getting up to speed with this approach in general would be much appreciated.

The compiler error is:

main.cpp: In function 'void test()':
main.cpp:23:19: error: no matching function for call to 'std::vector<std::shared_ptr<Base> >::push_back(std::shared_ptr<Derived>&)'
     v.push_back(pb);   // compile error wants, std::shared<Base> not Derived
                   ^
main.cpp:23:19: note: candidates are:
In file included from /usr/local/include/c++/4.8.2/vector:64:0,
                 from main.cpp:2:
/usr/local/include/c++/4.8.2/bits/stl_vector.h:901:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::shared_ptr<Base> _Alloc = std::allocator<std::shared_ptr<Base> > std::vector<_Tp, _Alloc>::value_type = std::shared_ptr<Base>]
       push_back(const value_type& __x)
       ^
/usr/local/include/c++/4.8.2/bits/stl_vector.h:901:7: note:   no known conversion for argument 1 from 'std::shared_ptr<Derived>' to 'const value_type& {aka const std::shared_ptr<Base>&}'
/usr/local/include/c++/4.8.2/bits/stl_vector.h:919:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::shared_ptr<Base> _Alloc = std::allocator<std::shared_ptr<Base> > std::vector<_Tp, _Alloc>::value_type = std::shared_ptr<Base>]
       push_back(value_type&& __x)
       ^
/usr/local/include/c++/4.8.2/bits/stl_vector.h:919:7: note:   no known conversion for argument 1 from 'std::shared_ptr<Derived>' to 'std::vector<std::shared_ptr<Base> >::value_type&& {aka std::shared_ptr<Base>&&}'
1

1 Answers

4
votes

Derived private inherit from Base which means Derived has a Base not Derived is a Base. Change to

class Derived : public Base
//              ^^^^^^