构造函数采用shared_ptr

时间:2015-01-26 22:45:44

标签: c++ c++11 typedef shared-ptr make-shared

我有这样的情况

struct Foo
{
    Foo(int x, int y) : x(x), y(y)
    {
    }
    int x, y;
};

class Bar
{
public:
    typedef std::shared_ptr<const Foo>  ConstFooPtr;
    typedef std::shared_ptr<Foo>        FooPtr;

    Bar(int index = 0, FooPtr ptr = FooPtr()) : index_(index), ptr_(ptr)
    {
    }

private:
    ConstFooPtr ptr_;
    int index_;
};

我想制作Bar,我想到了2种方法

Bar::FooPtr ptr(new Foo(1, 2)); //1

auto ptr2 = std::make_shared<Bar::FooPtr::element_type>(42, 13); //2

auto bar = Bar(0, ptr);

第一个是非常通用的,因为如果我要更改FooPtr的类型,也许我不需要改变这个代码。但它使用的是new,这是不好的。

第二个没有使用new,但它假定它是shared_ptr,这也不是一般的。

有没有什么方法可以让它发挥作用并且是一般的?或者也许我永远不应该在构造函数中使用一些ptrs?

(我将ptr存储到const Foo,因为我会复制Bar并更改index_,但data中的ptr_将是相同 - 您可以假设Foo对某些容器来说很重要)

1 个答案:

答案 0 :(得分:2)

只需滚动您自己的make_shared版本,并将其作为Bar的静态成员:

template<typename... Args>
static FooPtr make_shared_foo(Args... args)
{
    return ::std::make_shared<Foo>(::std::forward<Args>(args)...);
}

通过这种方式,您可以像这样使用指针:

auto ptr3 = Bar::make_shared_foo(3,14159);

当然,没有什么可以阻止你把它带到它的最终版本:

Bar(int index = 0) : index_(index), ptr_(FooPtr())
{ }

template<typename... Args>
Bar(int index, Args... args)
    : index_(index)
    , ptr_(new Foo(::std::forward<Args>(args)...))
{ }

只允许您将构造函数的参数传递给Bar,然后转发它们以创建指向Foo的指针供自己使用。