这是我在 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);
}
}
如果需要在此处发布任何其他信息或完整代码,请告诉我。
最佳答案
有两种选择:
在基类中提供一个
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); } } }
使用
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/