Отдельные заголовочные файлы для реальных классов - C++

1112 Здесь важен порядок этапов. Вы продвигаете этап $match после этапа $sample , который сначала помещает $size в целые документы, а затем применяет этап $match к $sample d документирует документы.

Итак, наконец, вам нужно продвинуть стадию $sample после стадии $match. Порядок должен быть

const limit = Number(req.query.limit || 1);

  const difficulty = req.query.difficulty;
  const category = req.query.category;
  const settings = []

  if (difficulty && category) {
    settings.push({
      $match: {
        difficulty: difficulty,
        category: category
      }
    })
  } else if (difficulty && category == null) {
    settings.push({
      $match: {
        difficulty
      }
    })
  }

  if (difficulty == null && category) {
    settings.push({
      $match: {
        category
      }
    })
  }

  setting.push({
    $sample: {
      size: limit
    }
  })
  console.log(settings);

  Question.aggregate(settings)

5
задан Navaneeth K N 18 February 2009 в 01:38
поделиться

7 ответов

Что-то, что Вы могли бы рассмотреть, в зависимости от остальной части Вашего дизайна, фабрика, где Ваш абстрактный класс имеет статический метод (или несколько статических методов, в зависимости от того, как Вы реализуете его), который создает соответствующий подкласс и возвращает его как IConverter*. С этим можно выставить только абстрактное определение в заголовочном файле и иметь все определения реального класса и реализации в единственном .cpp файле наряду с реализацией суперкласса. Это становится немного громоздким, если Ваш подкласс является большим, но с меньшими классами он сокращает количество файлов, которыми необходимо управлять.

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

На основе комментариев я рекомендовал бы структуру как это:

IConverter.h ==> определение IConverter
Converters.h ==> определения всех подклассов
IConverter.cpp ==> включают IConverter.h и Converters.h, содержат реализацию абстрактной функциональности IConverter (статический метод фабрики и любая наследуемая функциональность)
TextConvter.cpp, ImagerConverter.cpp, и т.д. ==> разделяют cpp файлы для каждого подкласса, каждый содержащий IConverter.h и Converters.h

Это позволяет Вам только включать IConverter.h в любые клиенты, которые используют фабрику и универсальную функциональность. Помещение всех других определений в единственном заголовке позволяет Вам консолидировать, если они - все в основном то же. Отделитесь cpp файлы позволяют Вам использовать в своих интересах преимущества компилятора, упомянутые Brian. Вы могли встроить определения подкласса в заголовочных файлах, как упомянуто, но это действительно не покупает Вас ничто. Ваш компилятор обычно более умен, чем Вы когда дело доходит до оптимизации как встроенный.

1
ответ дан 18 December 2019 в 13:19
поделиться

Вы, вероятно, получите ответы оба пути.

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

Сложные преобразования, вероятно, заслуживают своих собственных пар файла.

1
ответ дан 18 December 2019 в 13:19
поделиться

Лучший ответ на это - то, что легче считать. Один долгий исходный файл будет трудным для Вас и других программистов для следования. С другой стороны, многие крошечные (половина полного экрана) исходные файлы так же плохи.

1
ответ дан 18 December 2019 в 13:19
поделиться

Это не требуется. Это - в основном личный выбор.

Если реализация проста для каждого класса, можно поместить их всех в один.h и один .cpp

Если реализации немного дольше, то это - вероятно, инструмент для очистки для использования отдельного.h и .cpp файла для каждого.

Некоторые преимущества использования другого .h/.cpp для каждого класса:

  • Это сохранит код организованным и чистым
  • Уменьшенная работа компиляции: изменение в одной из реализаций не должно будет перекомпилировать всех других
  • Быстрее компиляция времени: Несколько компиляторов могут скомпилировать несколько файлов сразу, таких как / переключатель MP Visual Studio. С несколькими файлами у Вас будет более быстрое время компиляции.
  • Другие файлы могут включать только, в чем они нуждаются вместо всего
  • Более быстрое время ссылки: Соединение времени будет уменьшено из-за пошаговой компоновки
  • Используя управление версиями можно оглянуться назад только на изменения в конкретном производном классе, вместо того, чтобы иметь необходимость пройти все изменения, внесенные в крупный 1 .h/.cpp файл, чтобы найти что одно изменение в конкретном производном классе.
8
ответ дан 18 December 2019 в 13:19
поделиться

Вам будут нужны определения реальных классов для создания объектов, таким образом, необходимо будет поместить те определения в.h файл где-нибудь. То, какой файл Вы вставляете их, ваше дело.

1
ответ дан 18 December 2019 в 13:19
поделиться

Один из основных моментов создания интерфейсного класса - то, так, чтобы клиенты могли быть, зависят от абстрактного интерфейса, а не конкретной реализации, и Вы затем свободны изменить реализацию, не влияя на клиенты.

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

1
ответ дан 18 December 2019 в 13:19
поделиться

Вы, вероятно, были бы более обеспеченными фабриками использования или указателями функции.

Однако один особенно противный путь, который приходит на ум, использует макрос для объявления реальных классов. Например:

У основания IConverter.h включают следующий макрос

#define DECLARE_CONVERTER_CLASS(CLASS_NAME) \
class CLASS_NAME : public IConverter\
{ \
    public: \
    CLASS_NAME() {} \
    virtual void DoConversion(); \
}; \

Затем в MyConverter1.cpp

DECLARE_CONVERTER_CLASS(MyConverter1)

virtual void MyConverter1::DoConversion()
{
    ...
}

Фу :-)

1
ответ дан 18 December 2019 в 13:19
поделиться
Другие вопросы по тегам:

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