C++: различие между NVI и шаблонными шаблонами метода?

Каково различие между NVI (Невиртуальный Интерфейс) и Шаблонными шаблонами Метода?

Они кажутся очень похожими, и я читал и что они - в основном то же и что они тонко отличаются с Шаблоном, являющимся так или иначе более общим.

7
задан manlio 27 March 2016 в 21:50
поделиться

2 ответа

NVI - это идиома, Template Method - это шаблон. NVI - это реализация шаблона метода шаблона с использованием динамической отправки в C ++; также возможно создание шаблонных методов на C ++ с использованием метапрограммирования шаблонов, чтобы исключить динамическую отправку.

Шаблон является более общим, чем идиома, и языки могут использовать разные идиомы для реализации шаблона.

12
ответ дан 6 December 2019 в 08:41
поделиться

Как уже было сказано, NVI - это идиома программирования, связанная с категория языков. Среди прочих его продвигал Херб Саттер, потому что он помогает обеспечивать выполнение контрактов:

  • инварианты классов
  • контракты функций (утверждения по переданным параметрам и сгенерированное возвращаемое значение)
  • повторяющиеся операции (например, ведение журнала)
  • управление по сгенерированным исключениям (хотя и плохая идея;))

Однако реализация на самом деле может значительно отличаться, например, другим примером реализации NVI является ее объединение с Pimpl:

class FooImpl;

class Foo
{
public:
  enum type { Type1, Type2 };

  Foo(type t, int i, int j);

  int GetResult() const;

private:
  FooImpl* mImpl;
};

И для реализации:

struct FooImpl
{
  virtual ~FooImpl();
  virtual int GetResult() const;
};

class FooType1: public FooImpl
{
public:
  FooType1(int i, int j);
  virtual int GetResult() const;
private:
  /// ...
};

I ' Мы всегда находили, что это лучше передает суть. Вы уже догадались?

Главное, что virtual - это деталь реализации. А раскрывать детали реализации в интерфейсе - плохая идея, потому что вы можете захотеть их изменить.

Более того, детали реализации имеют тенденцию мешать двоичной совместимости. Например, добавление нового виртуального метода в класс может изменить макет виртуальной таблицы (общая техника реализации) и, таким образом, нарушить двоичную совместимость.В gcc вам нужно убедиться, что вы добавили его последним (среди виртуальных), если вы хотите сохранить совместимость.

При использовании комбинации NVI + Pimpl, описанной выше, в представленном классе вообще нет виртуального (даже частного). Схема памяти имеет обратную и прямую совместимость. Нам удалось добиться бинарной совместимости.

Здесь мы используем сразу несколько шаблонов:

  • Шаблонный метод
  • Стратегия (поскольку мы можем менять местами указатель по желанию)
  • Фабрика (чтобы решить, какую реализацию мы получим)
9
ответ дан 6 December 2019 в 08:41
поделиться
Другие вопросы по тегам:

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