构造函数采用 shared_ptr

Constructor taking shared_ptr

我有这样的情况

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_,但 dataptr_将是相同的 - 你可以假设 Foo 对于某些容器来说很大)

只需滚动您自己的 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 的指针供其自己使用。