gpt4 book ai didi

c++ - 从复合模式结构中删除元素

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:13 25 4
gpt4 key购买 nike

假设我们有最简单的结构,类 ComponentLeaf : ComponentComposite : ComponentLeaf 类的每个对象都有一个 int id 来赋予它自己的身份。复合类会有这样的东西:

class Composite : public Component
{
public:
void removeComponent(Component*);
// other stuff
private:
std::vector<Component*> coll;
};

和叶类之类的东西:

class Leaf : public Component
{
public:
//stuff
int getID();
private:
int id;
};

问题是如何定义函数removeComponent(Component* cmp)。 cmp 实际上是一个 Leaf,但我需要访问 Component vector coll,所以它需要是一个 Component(我认为)。 removeComponent 方法接受一个 Leaf 对象,并从整个结构中删除具有相同 ID 的所有其他 Leaves。

现在,我想到了两种方法(都行不通:P):

第一

void Composide::removeComponent(Component* cmp)
{
std::vector<Component*>::const_iterator it;
for(it = coll.begin(); it != coll.end(); ++it)
{
(*it)->removeComponent(cmp);
// where removeComponent is defined as virtual in Component, but
// the problem is that Leaf cannot erase itself from the collection
}

}

第二

void Composide::removeComponent(Component* cmp)
{
std::vector<Component*>::const_iterator it;
for(it = coll.begin(); it != coll.end(); ++it)
{
if((*it)->equals(*cmp))
it = erase(it);
// But here I can't define equals function for Composite elements,
// so then I'd have to make functions which return the type of Component,
// and in case of Composite call recursively the function and
// in the case of Leaf call the equals() function and erase if needed.
// This however looks like really bad OOP practice, and I'd like to avoid
// using those methods which return type..
}

}

必须有一种简洁、漂亮的方法来做到这一点。我有点认为该方法应该类似于上面提到的第一种方法,只是我真的不知道如何使 Leaf 能够从 vector 中删除自己。请帮帮我? :)

最佳答案

您似乎对 Component 到底是什么感到困惑。它是某个业务对象,还是表示树节点的类?如果它是一个树节点,那么所有树节点都应该支持相同的操作,以便于递归。

因此,我会将 removeComponent() 的定义移动到基础 Component 类中,并使其成为虚拟的。您可以在 Component 中提供一个空的实现。

你的复合实现很简单:

void Composide::removeComponent(Component* cmp)
{
std::vector<Component*>::const_iterator it;
for(it = coll.begin(); it != coll.end(); ++it)
{
if((*it)->equals(*cmp))
it = erase(it);
else
(*it)->removeComponent(cmp);
}
}

编辑:关于 Id 的

同样,我认为您可能混淆了两个概念:组件 ID 和组件。(也许将 Component 重命名为 TreeItem 会更好?)

您当前的 removeComponent() 函数接受一个 Component 指针,因此推断任何 Component 都可以从树中移除(包括 >复合 Material )。这对我来说似乎是正确的。您可能需要删除 Composites。因此,您可以简单地比较指针。

但是,您随后似乎在比较只有 Leafs 具有的 Id(通过假设的相等重载)。

如果您想提供一个额外的函数来通过 Id 删除,那么我会将 GetID() 函数也移到基础 Component 类中,并与它进行比较。 Composite 对象可以返回 -1 或其他一些空标记。

例如。

void Composite::getID()
{
return -1;
}

void Composide::removeComponent(Component* cmp)
{
std::vector<Component*>::const_iterator it;
for(it = coll.begin(); it != coll.end(); ++it)
{
if((*it) == cmp)
it = erase(it);
else
(*it)->removeComponent(cmp);
}
}

void Composite::removeComponentById(int id)
{
std::vector<Component*>::const_iterator it;
for(it = coll.begin(); it != coll.end(); ++it)
{
if((*it)->getID() == id)
it = erase(it);
else
(*it)->removeComponentById(id);
}
}

关于c++ - 从复合模式结构中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12365930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com