Можно ли использовать std:: make_unique с абстрактным интерфейсом?

Рассмотрим следующую строку кода:

auto source1 = std::unique_ptr<IGpsSource>(new GpsDevice(comPort, baudrate));
auto source2 = std::unique_ptr<IGpsSource>(new GpsLog(filename));

Как это можно записать с помощью новой функции std:: make_unique, поддерживаемой VS 2013? Возможно ли это? *

* Моя проблема в том, что я не знаю, как сказать "make_unique", какой объект нужно создать. Поскольку передаются только параметры конструктора, похоже, нет контроля над этим...

Ответ 1

Да, вы можете, конечно, использовать make_unique для этого, но это не так полезно, как вы могли бы захотеть. У вас есть следующие опции:

std::unique_ptr<IGpsSource> source1 = std::make_unique<GpsDevice>(comPort, baudrate);
auto source2 = std::unique_ptr<IGpsSource>{ std::make_unique<GpsLog>(filename) };

Я бы сказал, что реальный вопрос: "Почему вы этого хотите?"

  • В отличие от make_shared, make_unique не имеет преимуществ по сравнению с new. Поэтому, если вам нужен контроль над типом указателя, то, что вы делаете, просто отлично.

  • Зачем вам нужен указатель для ввода на IGpsSource в первую очередь? Существует неявное преобразование из std::unique_ptr<Derived> rvalues ​​в std::unique_ptr<Base> rvalues. Поэтому, если вы на самом деле вызываете make_unique для инициализации указателя IGpsSource, он будет работать нормально. И если вы хотите перенести указатель где-нибудь, вам все равно придется std::move, после чего преобразование может повториться.

Ответ 2

std::unique_ptr<Base> base_ptr = std::make_unique<Derived>();

Как сказал Angew, все вышеперечисленное должно работать нормально. При условии, что Derived использует публичное наследование. Просто хотел добавить это для полноты.

Ответ 3

Умные указатели для тех, кто не знает, что они делают. Все эти улучшения, на мой взгляд, являются просто сахарным покрытием для реальной вещи, которая является необработанным указателем. Забудьте все это (если вы не пойдете на собеседование), и у вас все будет хорошо. Я имею в виду все те вещи, которые вы должны выучить, запомнить и визуализировать в своих головах, как они работают, они не стоят того, и реальные причины, по которым они здесь, - это удовлетворение эго тех, кто называл себя хранителями C++. Преимущества интеллектуальных указателей, на которые они претендуют, действительно сводятся на нет вытекающими отсюда недостатками, а недостатки заключаются в умственной сложности, которую они вынуждают программиста учить годами, не говоря уже о том, что код выглядит намного сложнее. С каждым выпуском C++ становится все громче и громче. Я держу пари двадцать лет, я не смогу читать C++ коды, написанные для того же приложения, которое я написал 10 или 15 лет назад