2

I have problem, I want to create unique pointer to vector of Base objects. I want keep in this vector subclass of Base (SubClass), but i have problem with initialization, because Base class is virtual.

std::unique_ptr<std::vector<Base>> baseVector = std::make_unique<std::vector<Base>>();
SubClass newObject();
baseVector->push_back(newObject);
5
  • 3
    You don't need a pointer to the vector, but a pointer to the base class. Please try to find a good beginners book as it will all be explained there. Commented Jun 8, 2017 at 11:41
  • You should use pointer to Base for storing the objects. See this stackoverflow.com/questions/2394581/… Commented Jun 8, 2017 at 11:41
  • 5
    You probably want std::vector<std::unique_ptr<Base>> instead (or std::vector<Base*> if vector doesn't have ownership). Commented Jun 8, 2017 at 11:41
  • 1
    You'll need a vector of pointers to your base class. Also, why do you need a pointer to a vector? What does it give you that aplain vector instance does not? Commented Jun 8, 2017 at 11:42
  • 2
    SubClass newObject(); is a function declaration BTW. Commented Jun 8, 2017 at 11:42

2 Answers 2

6

Short Version: You don't want a dynamic pointer to a collection of Base; you want a collection of dynamic pointer-to-Base.

You seem to be misunderstanding where to place std::unique_ptr in your polymorphic collection. It isn't the collection that needs to be pointers for polymorphism to work; it's the object held within.

For example:

#include <iostream>
#include <vector>
#include <memory>

struct Base
{
    virtual ~Base() {}

    virtual void foo() const = 0;
};

class DerivedOne : public Base
{
public:
    virtual void foo() const
    {
        std::cout << "DerivedOne\n";
    }
};

class DerivedTwo : public Base
{
public:
    virtual void foo() const
    {
        std::cout << "DerivedTwo\n";
    }
};

int main()
{
    std::vector< std::unique_ptr<Base> > objs;

    objs.emplace_back(std::make_unique<DerivedOne>());
    objs.emplace_back(std::make_unique<DerivedTwo>());

    // via operator[]
    objs[0]->foo();
    objs[1]->foo();

    // via range-for
    for (auto const& p : objs)
        p->foo();

    // via iterators
    for (auto it = objs.begin(); it !=objs.end(); ++it)
        (*it)->foo();
}

Output

DerivedOne
DerivedTwo
DerivedOne
DerivedTwo
DerivedOne
DerivedTwo

Whether you want the collection itself to be managed dynamically via a smart pointer is unrelated (and somewhat questionable) to this issue.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your solution :)
Yes, this worked for me and I made a complicated example out of it since my needs vary a tad from this. But it works, thanks.
2

A vector of Base doesn't support polymorphism. For this you need references or pointers or even better smart pointers:

auto baseVector = std::make_unique<std::vector<Base*>>();
auto baseVector = std::make_unique<std::vector<std::unique_ptr<Base>>>();

add elements via

baseVector.push_back(std::make_unique<SubClass>());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.