0

想象一下有一个Node可以容纳多个父母和多个孩子的类:

class Node {
    public:
        Node();
        virtual void addParent(Node *parent);
        virtual void addChild(Node *child);
    private:
        vector<Node*> m_parents;
        vector<Node*> m_children;
};

问题是每次向节点添加父节点时,必须更新节点m_parents并且必须更新父节点m_children;这会创建一个无限循环。

void Node::addParent(Node *parent)
{
    if (m_parents.lacks(parent)) { // supposing such method exists
        m_parents.push_back(parent);
    }
    parent->addChild(this);
}

void Node::addChild(Node *child)
{
    if (m_children.lacks(child)) {
        m_children.push_back(child);
    }
    child->addParent(this);
}

如您所见,这不好。我已经设法通过四种添加方法而不是两种方法来解决这个问题,但感觉有点愚蠢。附加的两个方法都已声明privateprotected因此它们不能被其他人调用。这是原始addParent方法和新方法rawAddChild

void Node::addParent(Node *parent)
{
    if (m_parents.lacks(parent)) {
        m_parents.push_back(parent);
    }
    parent->rawAddChild(this);
}

void Node::rawAddChild(Node *child)
{
    if (m_children.lacks(child)) {
        m_children.push_back(child);
    }
    // Doesn't call for parent's method
}

addChild()这对于和显然是相同的rawAddParent()

然而,这感觉不是一个合适的解决方案,“外人”当然不清楚为什么会有这些addChild方法rawAddChild。我的逻辑有问题吗?如果有,我应该如何解决这个问题?还是我的解决方案已经很好了?

4

3 回答 3

7

我建议仅使用以下两种方法之一进行实际操作:

void Node::addParent(Node *parent)
{
    if (m_parents.lacks(parent)) {
        m_parents.push_back(parent);
    }
    if (parent->m_children.lacks(this)) {
        parent->m_children.push_back(this);
    }
}

void Node::addChild(Node *child)
{
    child->addParent(this);
}
于 2013-06-04T16:56:11.127 回答
0

我会测试向量是否已经包含元素(可能使用集合而不是向量)

void Node::addParent(Node *parent)
{
    if (m_parents.lacks(parent)) { // supposing such method exists
        m_parents.push_back(parent);
    }
    if (parent->m_childs.find(this)==set::end)
        parent->addChild(this);
}

void Node::addChild(Node *child)
{
    if (m_children.lacks(child)) {
        m_children.push_back(child);
    }
    if (child->m_parents.find(this)==set::end)
        child->addParent(this);
}
于 2013-06-04T16:59:33.850 回答
0

你应该抽象一点。

bool Node::addParent(Node *parent)
{
    if (m_parents.lacks(parent)) { // supposing such method exists
        m_parents.push_back(parent);
        parent->updateRelationShip(parent,this);
        return true;
    }
    return false;
}

bool Node::addChild(Node *child)
{
    if (m_children.lacks(child)) {
        m_children.push_back(child);
        child->updateRelationShip(this,child); 
        return true;
    }
    return false;
}
void Node::updateRelationship(Node*parent, Node* child){
   parent->addChild(child);
   child->addParent(parent);
}
于 2013-06-04T17:02:59.353 回答