- Канал содержит элементы типа E.
- Канал также имеет порт, который дает доступ к элементам в канале.
Это должно выглядеть примерно так:
template<
typename E>
class IOutPort{
public:
...
/**
* Takes an element (chosen by the implementation) that is in channel
*
* @return
* The element
*/
virtual E take() = 0;
};
template<
typename E>
class IChannel {
public:
...
/**
* Gives access to the out port of this channel
*
* @return
* A smart pointer to the channel's port
*/
virtual std::shared_ptr<IOutPort<E>> getOutPort() = 0;
};
Они оба должны ссылаться на себя..
Кроме того:
- Имплементация канала не может предоставить собственный shared_ptr для реализации порта во время построения (поскольку он еще не завершен)
- Если оба используют сильные ссылки, они никогда не будут освобождены
- Некоторый пользовательский код может захотеть сохранить указатель порта для последующего использования... Так что в это время канал все еще должен существовать!
Разрыв круга с помощью weak_ptr может привести к преждевременному разрушению канала!
Какому шаблону лучше всего следовать, не объединяя два интерфейса??
EDIT: @Edwin Да, я уже проверил существующие обсуждения... Ответ, который я ищу, более этичен, чем технический...
По существу, каковы преимущества композиции на таком языке, как C++, в котором отсутствует управление памятью и удобство использования «этого» во время построения, когда составному объекту требуется доступ к компоновщику?
Я считаю, что единственным решением является реализация композитора и (частно) всех интерфейсов компонентов в одном классе (чтобы решить проблему связи между компонентами и композитором). И, возможно, предоставить конкретные представления этого уникального класса, чтобы казалось, что отношение «является» в отношении «имеет»... Но в таком сценарии все преимущества композиции теряются!