我有这样的情况
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
对某些容器来说很重要)
答案 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
的指针供自己使用。