GOF Composite Design Pattern CompositeObject :: Удалить рекурсивную реализацию в переполнении стека

Это часть вопроса из моего вопроса, заданного в Просмотр Кода Веб-сайт:

GOF Составная реализация шаблона проектирования с использованием современного C ++

Сообщение содержит полную информацию / реализацию о нем, но здесь я публикую этот вопрос, чтобы понять следующую информацию:

How to implement CompositeEquipment::Remove?.

Исходя из моего понимания, он должен выполнять рекурсивный поиск по всему составному объекту, в который был вызван клиент, и recursively all its child objects which can also be of composite type, Просто чтобы проиллюстрировать сверху реализацию, если клиент напишет как cabinet->Remove(bus); он не будет удалять объект шины, так как он является дочерним chassis объект. Это кажется мне неправильным. Однако я не могу реализовать CompositeEquipment::Remove таким образом, что он ищет рекурсивно, если сами дочерние объекты являются составными.

До сих пор я пришел со следующей реализацией, которая просто ищет составные объекты, которые клиент задействовал для Remove метод.

//To find out whether items are in the composite objects
class Name_Equal {
private:
Equipment::EquipmentSmartPtr val;
public:
Name_Equal(const Equipment::EquipmentSmartPtr& v) :val(v) { }
bool operator()(const Equipment::EquipmentSmartPtr& x) const {
return (x->Name() == val->Name());
}
};

void CompositeEquipment::Remove(EquipmentSmartPtr entry) {
find_equipment(_equipment, entry);
}

void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
}
}

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

0

Решение

Есть два варианта:

  1. Обеспечить virtual функция Remove в базовый класс и сделать его реализацию noop. Затем добавьте еще несколько строк в CompositeEquipment::find_equipment,

    void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
    EquipmentSmartPtr& entry){
    Name_Equal eq(entry);
    auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
    if (itrpos != std::end(vec)) {
    vec.erase(itrpos);
    } else {
    for ( EquipmentSmartPtr sptr : vec )
    {
    sptr->Remove(entry);
    }
    }
    }
    
  2. использование dynamic_cast определить, является ли элемент композита также композитным. Если это так, позвоните Remove в теме. Я предпочитаю этот вариант.

    void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
    EquipmentSmartPtr& entry){
    Name_Equal eq(entry);
    auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
    if (itrpos != std::end(vec)) {
    vec.erase(itrpos);
    } else {
    for ( EquipmentSmartPtr sptr : vec )
    {
    Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
    if ( ptr )
    {
    ptr->Remove(entry);
    }
    }
    }
    }
    

Немного об именах … find_equipment кажется странным названием для функции. Я бы положил все это в Remove,

    void CompositeEquipment::Remove(EquipmentSmartPtr& entry){
std::vector<EquipmentSmartPtr>& vec = _equipment;
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
if ( ptr )
{
ptr->Remove(entry);
}
}
}
}
1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector