Вопрос

В настоящее время я работаю над движком спрайтов на C++.У меня есть абстрактный класс IEngine с виртуальной функцией init_api.Это занимает пустоту*.

    //  Initialise the engines' API
//  api_params - void* to api parameters for initalisation
//  hWnd - window handle
virtual bool init_api( void* api_params, HWND hWnd ) = 0;

Затем у меня есть класс CEngineDX, реализованный в DirectX.Затем api_params преобразуется в D3DPRESENT_PARAMETERS*, чтобы его можно было использовать для инициализации DirectX.

//  Cast api_params to a D3DPRESENT_PARAMETERS
D3DPRESENT_PARAMETERS* presentParams = NULL;
presentParams = reinterpret_cast< D3DPRESENT_PARAMETERS* >( api_params );

Я вполне доволен этой настройкой, но хотел бы, если хотите, узнать мнение других программистов об этом «решении».

Спасибо за ответы!

Карл

Это было полезно?

Решение

Другой способ сделать это — просто иметь общий заголовок и разные файлы *.cpp для каждой реализации.Таким образом, вы можете включить в свой проект только файлы D3D или только файлы OGL.ИМО, лучше выбирать API во время компиляции, чтобы не связываться с обеими библиотеками.

Что касается пустоты*, то она мне не очень нравится.Я думаю, вам лучше определить свои собственные типы, а затем сопоставить их с типами API с помощью структур/классов-оболочек и определений типов.Вы можете объявить их и поместить фактическую реализацию в свои файлы *.cpp.

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

Другие советы

Это относительно распространенная проблема, связанная с изменением типов аргументов в иерархиях наследования;ваш подкласс хочет специализировать тип «api_params» из родительского класса.

Я думаю, что это нормально, но это C-подобно.Я думаю, что лучшим решением было бы сделать init_api невиртуальный и реализовать его с правильным типом в подклассе.Во всяком случае, скорее всего, D3DPRESENT_PARAMETERS Структура имеет смысл только с движком DirectX, так почему бы не разместить ее в подклассе, которому она логически принадлежит?

Ну, вы можете использовать шаблоны (если вам не нравится приведение типов), но в этом случае вам придется отказаться от вашей иерархии.

template<class T>
struct Engine {
   bool init_api(const T& params, HWND hWnd);
};

//specialize for DirectX
template<>
struct Engine <D3DPRESENT_PARAMETERS> {
  bool init_api(const D3DPRESENT_PARAMETERS& params, HWND hWnd) {
    return true;
  }
};

Но используйте что-то, что вписывается в общую схему вещей.

Мне не очень нравится этот API.Зачем использовать указатель void?Почему бы не сделать первый параметр указателем или ссылкой на D3DPRESENT_PARAMETERS?Вы знаете, что так и должно быть, верно?Это более безопасно с точки зрения типов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top