Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make_shared and abstract polymorphism

Is there any way I can use make_shared instead of shared_ptr for abstract types?

Example:

#include <memory>
#include <vector>

class Foo
{
public:
    virtual void fooFunc() = 0;
};

class Bar : public Foo
{
public:
    void fooFunc() {};
};

int main()
{
    std::vector< std::shared_ptr<Foo> > vec;

    vec.push_back(std::shared_ptr<Foo>(new Bar()));
    //vec.push_back(std::make_shared<Foo>(new Bar())); //doesn't work because Foo is abstract

    return 0;
}
like image 923
MrPlow Avatar asked Sep 17 '25 03:09

MrPlow


2 Answers

I ended up here because I didn't specify my inheritance as public. So I had:

class Bar : Foo 

instead of:

class Bar : public Foo 

Adding the public made shared_ptr<Foo> foo = make_shared<Bar>(...) work as expected

like image 144
Klepto Avatar answered Sep 19 '25 18:09

Klepto


You may use a std::static_pointer_cast if you want to be explicitly mentioning the cast:

int main()
{
    std::vector<std::shared_ptr<Foo>> vec;
    vec.push_back(std::static_pointer_cast<Foo>(std::make_shared<Bar>()));
}

But it also works without it:

vec.push_back(std::make_shared<Bar>());

Here's a demo showing the behaviour: Demo

I'd recommend not to use std::make_shared in combination with new. There is a performance concern here and in my opinion it's a good thing to avoid unbalanced new / deletes.

like image 26
stefan Avatar answered Sep 19 '25 17:09

stefan