Как стать автором
Обновить
8
0
Василий @VasilyK

Программист C++

Отправить сообщение

В вашем примере есть явное нарушение инкапсуляции, можно сделать так:


a->_result_by_module = std::function<int(int)>();

Хотя этого можно избежать.


есть недостаток: необходимость писать обертку для всех методов класса

Зачем? По умолчанию никакой необходимости в этом нет.


Думаю у такого подхода действительно есть много преимуществ, но не совсем тех, которые описаны в статье.

Если вы хотите выбирать реализацию в рантайме, то, скорее всего, вам нужна некоторая фабрика и, возможно, шаблон проектирования мост.


Класть каждую реализацию в отдельную динамической библиотеку мне не приходилось, но, как я понимаю, система плагинов QtCreator устроена подобным образом, так что можете посмотреть в эту сторону.


“Я правильно понимаю, что подобная задача возникает в медиаплеерах” — возможно, не сталкивался.

"Но текст сообщения, всё же, немного неправильный" — что вы имеете ввиду? Я рассматриваю это сообщение как небольшую подсказку, чтобы быстрее вспомнить что может быть не так. Если человек не понимает о чем речь, то ему наверняка придется идти на какой-то ресурс и искать более подробную информацию.


"Т.е. не хватает проверки времени выполнения инварианта указатель не nullptr" — полностью согласен


"operator ElementType() как explicit..." — скорее всего это правильно, но в данном случае возможно это не важно

Не совсем понял про деструкторы. Если вы говорите про класс widget, то деструктор необходим для нормальной работы Pimpl, если же говорите про класс PimplPtr, то, я думаю, нет никаких проблем явно написать конструкторы и операторы присваивания.


Второе совсем не понял, константные методы где? В классе widget? Зачем их реализовывать через интерфейс?

По поводу "не очень хорошего" кода, я с вами согласен, так как это имеет прямое отношение к рассматриваемому вопросу. Можно было показать в чем заключается проблема, и то, что unique_ptr по умолчанию запрещает попасть в неприятную ситуацию. И тут же описать использование move семантики.


Рассказать, почему деструктор нужно реализовывать в файле-реализации я думаю не стоит, так как это не совсем относиться к рассматриваемой теме, одна ссылка для ознакомления приведена в статье.


“не компилируется” — поправил.


“то причина у вас, получается одна” — еще как минимум одна причина — конструктор по умолчанию, я часто забывал написать явное создание Impl, после чего несколько минут искал ошибку.


По поводу реализации:


  • static_assert действительно можно опустить, но я его использую для более приятного сообщения об ошибке.
  • constexpr — пожалуй, вы правы.
  • Если вызывать конструктор из конструкторы, то можно было бы из первого вызывать второй (но не наоборот), но не думаю что это было бы лучше. ?? explicit
  • static_assert нужен как в конструкторе так и деструкторе — сообщения об ошибке отличаются, они указывают предполагаемую причину ошибку, если забыли конструктор, ты будет первое сообщение, если забыли деструктор — второе.
  • возможно "= default" было бы лучше
  • Согласен с вами, исправил исходный код.

Спасибо за комментарий.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность