将对象副本添加到容器的更好方法

时间:2012-06-14 14:35:03

标签: c++ pointers polymorphism shared-ptr

我有一个类Bar,它存储从BarItem派生的对象:

#include <list>
#include <memory>

class Bar {
public:
    typedef std::shared_ptr<BarItem> item_ptr;

    void add_item(item_ptr item) {
        items_.push_back(item);
    }

private:
    std::list<item_ptr> items_;
};

我有另一个类Note,它是BarItem的子类。目前要添加我正在做的Note对象的副本:

Bar my_bar;
Note my_note;

my_bar.add_item(Bar::item_ptr(new Note(my_note)));

哪个有点难看;我想知道是否有更好的方法或方法来实现自动化?

3 个答案:

答案 0 :(得分:1)

你可以将这个丑陋的部分移动到函数本身中:

template<typename ItemType>
void add_item(ItemType item) //change the signature
{ 
    items_.push_back(new ItemType(item));  //add the copy!
}

并将其命名为:

my_bar.add_item(my_note);

答案 1 :(得分:1)

你实际上无法避免复制(在C ++ 11中你可以使它成为一个移动),但你可以“自动化”它,这样你就可以通过重载每种类型的add_item函数来节省一些击键次数(可能是BarItem的孩子。)

template <class T>
typedef enable_if<is_base_of<BarItem, T>::value,void>::type add_item(const T& item) { /* or T&& */
    items_.push_back(item_ptr(new T(item)));
}

答案 2 :(得分:0)

在容器中使用指针是减少对象复制的一种方法。但是你处理Note对象创建的方式涉及通过复制构造函数复制它!

你能避免拥有一个对象,而是有一个指向该对象的指针吗?您可以通过将创建放在函数(工厂)中来完成此操作。该函数将获取构造函数的参数,new该对象并返回一个智能指针。