c++ - GOF 复合设计模式 CompositeObject::Remove Recursive Implementation in C++

标签 c++ design-patterns c++11 recursion composite

这是我在 codereview 中提出的问题的一部分网站:

GOF Composite Design Pattern Implementation Using Modern C++

帖子有关于它的完整信息/实现,但我在这里发布这个问题以了解以下信息:

How to implement CompositeEquipment::Remove?.

根据我的理解,它应该在客户端调用的所有复合对象中进行递归搜索,并且递归地搜索它的所有子对象,这些子对象也可以是复合类型。只是为了说明上面的实现,如果客户端写为 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);
    }
}

如果需要在此处发布任何其他信息或完整代码,请告诉我。

最佳答案

有两种选择:

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

关于c++ - GOF 复合设计模式 CompositeObject::Remove Recursive Implementation in C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26569695/

相关文章:

c++ - std:sort 与插入 std::set

c++ - 如何知道析构函数中的堆栈损坏来自何处?

c++ - 无法将带有 bool 网格的文本文件读入 vector 的 vector 中

c++ - 如何使用带有 lambda 仿函数参数的 requires 子句?

c++ - 如何创建 QList 的深拷贝 (Qt 4.8)

c++ - 竞争隐式和模板复制构造函数

c++ - 智能指针的使用

design-patterns - 将数据从一个grails操作转移到另一个

java - 这个简单工厂是否违反了开闭原则?

java - Selenium 结构化模式java