Интерфейсы и реализации
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.03.24 20:39
Оценка:
Здравствуйте!

Что-то туплю.

Обычно, если реализация зависит от платформы, не парюсь и делаю абстрактный интерфейс с чисто виртуальными функциями, делаю реализацию под target-платформу, а фабрика создаёт объект в куче и возвращает указатель на интерфейс, голенький или shared.

Из плюсов — можно при необходимости даже в рамках одной платформы и в рамках одного приложения сделать разные реализации и при необходимости использовать ту или иную реализацию, с возможностью выбора в рантайме.
Также плюсом является более простой интероп с другими языками, как с компилируемыми — например Дельфи, он знает о таблице виртуальных функций, да, думаю, и другие языки/платформы тоже подозревают, так и со скриптовыми языками, если захочется встроить что-то в программу.

Из минусов — использование динамической память, и все вызовы идут через vtbl, что само по себе не добавляет производительности, но и мешает оптимизации, и довольно часто приходится использовать dynamic_cast, чтобы из указателя на интерфейс получить указатель на конкретную реализацию, что тоже немного бъёт по перфомансу

Но, подумалось, а может попробовать сделать что-то более статическое? Да, тут сразу минус простой интероп, зато оптимизация, отсутствие виртуальности. И потенциальная возможность без геммора запихать код во встройку, в какой-нибудь микроконтроллер

Ну, допустим, есть класс окна и методы для работы с изображением курсора:
class Window
{
    Cursor createStockCursor(EStockCursor sc);
    Cursor serCursor(Cursor c);
};


Для винды, например, класс Cursor будет каким-то таким:
class Cursor // movable non-copiable
{
    HCURSOR hCursor = 0;

    ~Cursor()
    {
        DestroyCursor(hCursor);
    }
};


Тут проблема — HCURSOR системно зависимый, и тут либо в каждом хидере каждого класса обложиться ifdef'ами при определении раскладки класса, либо обложится ifdef'ами и инклюдить соответствующую реализацию.

В принципе, оба варианта рабочие, только в первом все кишки всех реализаций будут торчать наружу в хидере, во втором варианте они чутка скрыты, но тоже торчат наружу, если чуть копнуть. Ну, и ещё такой вариант подразумевает практически обязательное разделение на .h/.cpp.

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

Можно ещё попробовать через странные рекурсивные шаблоны, как в WTL, но это не очень интуитивно и слегка геморойно.

Пока пишу под компы, конкретно под винду, с прицелом на кроссплатформу, но точно знаю, что когда-нибудь захочется и в STMку запихать

В общем, как бы и на елку залезть, и жопу не ободрать?
Есть идеи, как сделать шоколадно?
Маньяк Робокряк колесит по городу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.