Интерфейс вместо Pimpl
2022-11-14 00:09Для изоляции реализации от интерфейса в Си++ обычно применяют идиому Pimple. Сергей Тарасов предлагает альтернативное решение, более простое: интерфейс в виде абстрактного класса. Надо будет попробовать переписать мой пример dependency-inversion-demo.

no subject
Date: 2022-11-14 08:33 (UTC)использовать '.' вместо ->
должно быть так:
book book1("Modern old-school C++", "Gang of thousands", 255);
cout << "Title: " << book1.title();
no subject
Date: 2022-11-14 08:44 (UTC)no subject
Date: 2022-11-15 04:02 (UTC)no subject
Date: 2022-11-14 09:03 (UTC)Подумаю насчет pimpl, там есть ккой-то резон, конечно. Насчет же интерфейса в виде абстрактного класса - ха, в плюсах же нету интерфейсов, да? Ну, многое еще предстоит освоить. Cake pattern, например.
Попробую ужо этот ваш pimpl в Скале. Спасибо.
no subject
Date: 2022-11-15 04:04 (UTC)no subject
Date: 2022-11-14 12:49 (UTC)IMHO
Date: 2022-11-14 13:25 (UTC)Правильный путь - это интерфейс выраженный через базовые классы (не обязательно абстрактные) и link-time initialization для производства конкретный классов.
Re: IMHO
Date: 2022-11-15 04:06 (UTC)no subject
Date: 2022-11-14 17:34 (UTC)Абстрактный класс - это классический способ, и такой защиты не дает, потому что добавление приватного поля меняет размер объекта.
no subject
Date: 2022-11-14 19:09 (UTC)no subject
Date: 2022-11-14 22:30 (UTC)no subject
Date: 2022-11-14 22:39 (UTC)no subject
Date: 2022-11-15 05:54 (UTC)no subject
Date: 2022-11-15 06:43 (UTC)no subject
Date: 2022-11-15 21:36 (UTC)no subject
Date: 2022-11-15 16:45 (UTC)no subject
Date: 2022-11-15 21:35 (UTC)no subject
Date: 2022-11-14 19:42 (UTC)https://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virtual-class-interface/2330745#2330745
no subject
Date: 2022-11-14 19:58 (UTC)no subject
Date: 2022-11-14 20:01 (UTC)"Abstract classes (pure virtuals) is something of which your clients must be aware: if you try to use them to reduce coupling and circular references, you need to add some way of allowing them to create your objects (e.g. through factory methods or classes, dependency injection or other mechanisms).
Also remember that by using inheritance you introduce a dependency on vtable layout. To maintain ABI you cannot change the virtual functions anymore (adding at the end is sort of safe, if the there are no child classes that add virtual methods of their own)"
В основном пимпл нужен для обслуживания внешних DLL интерфейсов.
no subject
Date: 2022-11-14 20:27 (UTC)Не вижу причин, почему бы абстрактным классам ровно так же не обслуживать внешние DLL интерфейсы. С меньшим количеством glue code.
no subject
Date: 2022-11-14 21:10 (UTC)в каком случае применение pure virtuals для интерфейсов нецелесообразно ;)
Тут много вариантов, даже у меня в практике было несколько разных случаев.
Самый простой указан в цитате: если клиент не под вашим контролем.
Вы выпускаете новую версию библиотеки (с расширенным, но совместимым интерфейсом)
и клиент не может перекомпилировать свой код,
а хочет просто заменить DLL.
Это накладывает жесткие ограничения на изменения интерфейса.
В реальности -- учитывая например, возможные разные хитрые оптимизации на стороне клиента,
интерфейс менять нельзя. Мы как то такой баг пару недель искали.
Тоже думали, что если новые функции в конце vtable добавлять, то ABI будет стабильна. Mistake.
То что вы считаете совместимым и то что компилятор считает совместимым --
это могут быть две большие разницы, понятные только экспертам, которых у вас в команде нет.
Другой вариант -- когда невозможно предоставить фэктори for interface instances.
Ну и наконец "for value types to minimize compile time dependencies."
Попробуйте например написать свой non-templated string class как DLL который
не весь определен в .h файле и к тому же независим от компилятора.
Как много там открытий чудных..
no subject
Date: 2022-11-14 20:34 (UTC)У меня тут один ловкий коллега зафигачил интерфейс к DLL через inheritance
no subject
Date: 2022-11-14 20:46 (UTC)просто если есть интерфейс то чисто теоретически мы предполагаем что подразумевается более чем одна имплементация
С другой стороны pimpl хорош для использования когда никаких разных имплементаций мы не подразумеваем, но по каким-то причинам хотим имплементацию спрятать, например по причине конфликтуюших хедеров или что-нибудь в таком роде
no subject
Date: 2022-11-14 21:20 (UTC)nz
Date: 2022-11-15 11:18 (UTC)Разделение интерфейса и реализации - не цель, а средство.
В зависимости от настоящей цели, инструменты могут применяться принципиально разные.
Интерфейсы (абстрактные классы) применяются прежде всего там, где требуется полиморфное поведение, т.е. реализаций может быть больше одной.
PImpl же применяется прежде всего там, где реализация одна, но требуется обеспечить к ней стабильный бинарный интерфейс (ABI). Например, для передачи типов между модулями, собранными разными версиями разных компиляторов. Интерфейсы здесь не особо подходят, потому что к каждому абстрактному классу присобачена таблица виртуальных методов. Добавили метод - ой, надо делать новый интерфейс.
Поэтому одно - не drop-in replacement другого, нет.