Конструктор, принимающий 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_;
};
Я хочу произвести Бар, и 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 ответ
Просто сверните свою собственную версию 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
для собственного потребления.