Лучше использовать '#ifdef' или наследование для кросс-компиляции?

Для следования из моего предыдущего вопроса о виртуальном и множественном наследовании (в кросс-платформенном сценарии) - после чтения некоторых ответов мне пришло в голову, что я мог упростить свою модель путем хранения сервера и клиентских классов, и замены платформы определенные классы #ifdefs (который является тем, что я собирался сделать первоначально).

Будет использование этого кода быть более простым? Это означало бы, что, по крайней мере, будет меньше файлов! Оборотная сторона - то, что это создает несколько "ужасное" и немного более твердое для чтения Foobar класс с тех пор существует #ifdefs повсеместно. Обратите внимание, что наш Unix, исходный код Foobar никогда не будет передаваться компилятору, таким образом, это будет иметь тот же эффект как #ifdef (так как мы также использовали бы #ifdef решить что платформа определенный класс для вызова).

class Foobar {
public:
  int someData;

#if WINDOWS
  void someWinFunc1();
  void someWinFunc2();
#elif UNIX
  void someUnixFunc1();
  void someUnixFunc2();
#endif

  void crossPlatformFunc();
};

class FoobarClient : public Foobar;
class FoobarServer : public Foobar;

Примечание: Некоторый материал (ctor, и т.д.) не учтенный для более простого примера.

Обновление:

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

6
задан Community 23 May 2017 в 10:32
поделиться

5 ответов

Preferably, содержат платформозависимый характер операций внутри методов, поэтому объявление класса остается одинаковым для всех платформ. (т.е. используйте #ifdefs в реализации)

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

.
10
ответ дан 8 December 2019 в 12:20
поделиться

Мое личное предпочтение - нажать ifdef magic в файлы make, чтобы исходный код оставался как можно более чистым. Затем иметь файл реализации для каждой платформы. Это, конечно, подразумевает, что вы можете придумать интерфейс, общий для всех поддерживаемых вами систем.

Редактирование:

Одним из распространенных способов обойти такой дизайн нижнего знаменателя для кросс-платформенной разработки является идиома - непрозрачный handle. Та же идея, что и маршрут экранирования ioctl(2) - иметь метод, возвращающий непрозрачную заранее объявленную структуру, определённую по-разному для каждой платформы (желательно в файле реализации), и использовать его только тогда, когда общая абстракция не содержит.

.
5
ответ дан 8 December 2019 в 12:20
поделиться

Если вы полностью уверены, что не будете использовать функции из другой ОС на одной скомпилированной, то использование ifdef's имеет массу преимуществ:

  1. Код и неиспользуемые переменные не будут скомпилированы в исполняемом файле (как бы ни помогала здесь умная ссылка)
  2. Легко будет увидеть, какой код живой
  3. Вы сможете легко включить в него файлы, зависящие от платформы.

Однако, классификация на основе ОС может иметь свои преимущества:

  1. Вы сможете быть уверены, что код компилируется на всех платформах при внесении изменений для одной
  2. Код и дизайн будет более чистым

Последнее достигается путем ifdefing специфичного для платформы кода в самих телах классов, или просто ifdefing из неподдерживаемых экземпляров ОС при компиляции.

2
ответ дан 8 December 2019 в 12:20
поделиться

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

0
ответ дан 8 December 2019 в 12:20
поделиться

Я предпочитаю перекладывать проблемы, специфичные для платформы, на листовые модули и пытаться обернуть их в общий интерфейс. Поместите специфические методы, классы и функции в отдельные модули трансляции . Пусть компоновщик и процесс сборки определит, какие специфические блоки перевода объединить. Это сделает код намного более чистым и облегчит время отладки.

Исходя из опыта, у меня был проект, в котором использовался #ifdef VERSION2. Я потратил неделю на отладку, потому что один модуль использовал #ifdef VERSION_2. Нюанс, который было бы легче поймать, если бы весь специфический код версии 2 был в модулях версии 2.

2
ответ дан 8 December 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: