Вывод точно в срок - PullRequest
       41

Вывод точно в срок

8 голосов
/ 17 декабря 2009

Существует менее распространенная идиома C ++, которую я несколько раз использовал для получения хорошего эффекта в прошлом. Я просто не могу вспомнить, есть ли у него обычно используемое имя для описания.

Это в некоторой степени относится к mixins , CRTP и type-erasure , но не относится конкретно к этим вещам.

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

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

Примером может быть то, что у вас навязчивый счетчик ссылок. Все ваши классы основаны на интерфейсе счетчика ссылок, но вы хотите, чтобы сам счетчик ссылок и реализация ваших методов подсчета ссылок появлялись один раз, поэтому вы помещаете их в производный шаблон - давайте назовем его ImplementsRC<T>. Теперь вы можете создать экземпляр так:

ConcreteClass* concrete = new ImplementsRC<ConcreteClass>();

Я скрываю такие вещи, как пересылка конструкторов, сформированных из множества шаблонных перегрузок и т. Д.

Итак, надеюсь, я ясно дал понять, что такое идиома. Теперь вернемся к моему вопросу - существует ли общепринятое или хотя бы общеупотребительное название для этой идиомы?

Ответы [ 9 ]

3 голосов
/ 17 декабря 2009

Это интересная идея. Однако я не собираюсь давать вам название уже установленной модели здесь, напротив, я собираюсь объяснить (несколько), почему я не думаю, что она уже есть.

Что это делает?

Это очень хороший способ избежать наследства ужасного алмаза.

Поскольку существует определенная путаница относительно цели метода, позвольте мне пояснить, почему я считаю, что это его цель:

class RefCounted
{
  virtual void addReference() = 0;
  virtual void removeReference() = 0;
};

class B: public RefCounted {};
class C: public RefCounted {};

class Diamond: public B, public C {};

Теперь у нас есть проблема. Если мы поместим реализацию RefCounted прямо в этот класс, он станет базовым классом, а не интерфейсом, и, следовательно, мы должны использовать виртуальное наследование, иначе члены данных будут дублированы (присутствуют как в B, так и в C).

Таким образом, идея состоит в том, чтобы отложить реализацию до последнего момента.

Преимущества:

  • Не нужно пытаться угадать использование B или C: там нет необходимости в виртуальном наследовании.
  • Компилятор приятно напомнит вам, если вы забудете добавить реализацию, так что вам не нужно об этом беспокоиться.

Неудобная:

  • Возложите бремя на клиента: вам лучше иметь фабрику для создания ваших объектов, тем более что один объект может реализовывать различные интерфейсы !!! Обратите внимание, что это может быть автоматизировано с помощью шаблонного метапрограммирования (более или менее) или может быть просто предоставлено автором класса.

Пример предоставления:

// d.h
class D: public B, public C
{
public:
  typedef ImplementRC<D> concrete_type;
  static concrete_type Build(int, int); // Named Constructor idiom

private:
  D(int,int);
}; // class D

// main.cpp
D::concrete_type myD = D::Build(1,2);

Так как зовут?

Я не могу придумать ничего, что точно соответствует этому. Были упомянуты Bridge и Decorator, но это совершенно особенное, и на самом деле не настолько ОО-ориентированное (например, это не произойдет в Java, поскольку у вас нет Multi-Inheritance), поэтому я сомневаюсь, что этот термин будет найден в книге ГФ.

Кроме того, на самом деле это не CRTP, потому что в CRTP есть своего рода цикл (основа знает о его производном классе), которого здесь не бывает> мы действительно строго линейны!

И, конечно же, это не идиома Pimpl, которая предлагает скрыть реализацию от клиента, а при использовании шаблона для реализации просто бросить его в лицо! (Шаблон может использовать Pimpl в качестве внутренней детализации)

Я скромно предлагаю jiti для Just In Time реализации , которая каким-то образом подражает названию, но ближе к сути, я думаю, деривация здесь - это всего лишь инструмент, а не цель .

Интересная идея в любом случае.

1 голос
/ 18 декабря 2009

Рассматривая ваш пример подсчета ссылок, вы можете получить некоторую радость, глядя на CComObject <>, который является одним из нескольких шаблонных классов, которые содержит ATL для обеспечения реализации IUnknown. Он также использует классы политики для изменения поведения. Естественно, отношение сигнал / шум, пытающееся Google по поводу концепции CComObject, очень низкое, потому что оно настолько вездесуще. Эта статья MSDN может дать вам больше «ключевых слов», чтобы помочь любому поиску.

http://msdn.microsoft.com/en-us/library/c43h4867(VS.80).aspx

[NB: Просто чтобы прояснить - я не предполагаю, что он использует CComObject, я полагаю, что это еще один популярный пример того же понятия, и поэтому на него можно было ссылаться в книге образцов или статья]

1 голос
/ 17 декабря 2009

Я определенно считаю, что это миксин, как и Брюс Экель (http://www.artima.com/weblogs/viewpost.jsp?thread=132988).

По моему мнению, одна из вещей, которая делает этот миксин, состоит в том, что это все еще одиночное наследование, которое отличается от использования MI для достижения чего-то подобного.

1 голос
/ 17 декабря 2009

Это миксин

1 голос
/ 17 декабря 2009

Вы ищете шаблон Декоратор ?

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

1 голос
/ 17 декабря 2009

Я не уверен, что у него есть имя, так как gf предположил, что оно немного похоже на шаблон моста. Это похоже на то, как вы привязываете функциональность к базовому классу.

Я предлагаю новое имя для этого, сутенер идиома. Пока вы сводите свой базовый класс;)

0 голосов
/ 10 июня 2011

Отвечая на мой собственный вопрос. Первый признак безумия? - нет, до этого было несколько признаков; -)

Во всяком случае, я так давно не писал, что я более или менее другой человек.

Я обнаружил, что остановился на названии mixover . Я обнаружил, что это прекрасно подходит и может считаться усовершенствованием миксина, а не исключением более общей концепции.

В последнее время я часто их использую, поэтому решил вернуться и обновить эту ветку.

0 голосов
/ 17 декабря 2009

Я не уверен, но является ли это "оптимизацией пустого члена c ++"?

и такое поведение реализовано с использованием шаблонов классов и частного наследования .

Это объясняется в журнальной статье Скотта Мейера "Подсчет объектов в C ++" .

0 голосов
/ 17 декабря 2009

Похоже идиома Pimpl ? Может быть использован необычным способом.

...