Своевременная деривация

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

Это несколько связано с mixins, CRTP и стиранием типа, но не является конкретно ни одной из тех вещей.

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

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

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

ConcreteClass* concrete = new ImplementsRC();

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

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

8
задан philsquared 17 December 2009 в 12:04
поделиться

8 ответов

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

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

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

It is an interesting idea. However I am not going to give you the name of an already established pattern here, on the very contrary I am going to explain (somewhat) why I don't think it already has one.

What does it do?

It is a very nice way to avoid the dread diamond inheritance.

Since there is some confusion apparently as to the purpose of the method, let me elaborate why I think this is its purpose:

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

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

class Diamond: public B, public C {};

Now, we here have a problem. If we put the implementation of RefCounted right in this class, it becomes a base-class instead of an interface, and thus we have to use virtual-inheritance or the data members will be duplicated (present in both B and C).

The idea is thus to defer the implementation to the last moment.

Advantages:

  • No need to try to second-guess the use of B or C: virtual inheritance is unnecessary there.
  • The compiler will nicely remind you if you forget to add the implementation, so no need to worry about that.

Inconvenient:

  • Put the burden on the client: you'd better have a factory to create your objects, especially since one object may implement various interfaces!!! Note that this might be automated with template meta-programming (more or less) or can simply been provided by the class author.

Example of providing:

// 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);

So what's the name ?

I can't think of anything that exactly matches this. Bridge and Decorator have been mentionned but this is quite special, and indeed not so OO-oriented (for example it won't happen in Java since you don't have Multi-Inheritance), so I doubt the term is going to be found in the GoF's book.

Also, it's not really the CRTP because there is a kind of loop in the CRTP (base being aware of its derived class) that does not happen here > we indeed are strictly linear!

And then, it's certainly not the Pimpl idiom, which proposes to hide the implementation away from the client while using a template for the implementation just throw it to its face! (The template could use Pimpl as an internal detail though)

I humbly suggest jiti for Just In Time Implementation, which mimicks the title somehow, but is closer to the point I think, derivation here being just a tool rather than a goal.

Interesting idea anyhow.

3
ответ дан 5 December 2019 в 20:16
поделиться

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

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

1
ответ дан 5 December 2019 в 20:16
поделиться

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

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

Я не уверен, но это «оптимизация C ++ для пустых членов»?

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

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

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

Это миксин

1
ответ дан 5 December 2019 в 20:16
поделиться

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

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

1
ответ дан 5 December 2019 в 20:16
поделиться

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

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

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

1
ответ дан 5 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

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