Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you add Derived objects to a vector of unique_ptr

How do you add different derived objects on to a vector of unique_ptr. with a vector of pointers i would create the item then a base pointer the to object and pass the pointer to be added, but make_unique dosn't take a pointer and i dont want to make overloaded functions for each type of derived objs.

class Base{...};

class Item:public Base{...};

Add_Item(Base* thing)
{   
    vec.push_back(thing);
}

//Problem with this is i have multiple derived objs and would rather have 1 Add_Item instead of multiple Add_Item functions.(if possible)
Add_Item(Item thing)
{   //this runs,but i lose anything that was in Item class
    vec.push_back(make_unique<Base>(thing));
}

/----------------------------------

follow up question, can you have a vector of unique_ptr inside another. i have tried this, (both ways you guys have shown me, with template Add_Item function and item Add_Item function). but both produced errors.

class Item: public Item
{  vector<unique_ptr<Base>>inv }

Item bag;
Item n_bag;
bag.Add_Item<I>(n_bag);

follow up follow up, no you cant, any recommendation for what kind of smart pointer to use

like image 970
user3085497 Avatar asked Feb 13 '23 11:02

user3085497


2 Answers

unique_ptr<T> has a constructor that moves from a unique_ptr<U> of a different type U as long as the pointer to the second type is implicitly convertible to the pointer to the first type and U is not an array type. So just use vec.push_back(make_unique<Item>(thing));. See demo.

To accept everything derived from Base, use a template:

template <typename D>
void AddItem(const D& thing) {
    vec.push_back(make_unique<D>(thing));
}

If D is not derived from Base, you get a compile error at the push_back.

like image 112
T.C. Avatar answered Feb 15 '23 10:02

T.C.


You want to make your AddItem() method a template method, so that you do not have to write a different function for each derived class. Modifying your existing implementation:

template <typename DERIVED>
void
AddItem (const DERIVED &thing)
{
    vec.push_back(make_unique<DERIVED>(thing));
}
like image 40
jxh Avatar answered Feb 15 '23 12:02

jxh