Здравствуйте!
Что-то туплю.
Обычно, если реализация зависит от платформы, не парюсь и делаю абстрактный интерфейс с чисто виртуальными функциями, делаю реализацию под 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ку запихать
В общем, как бы и на елку залезть, и жопу не ободрать?
Есть идеи, как сделать шоколадно?