两个成员互相依赖?

时间:2013-06-04 16:52:10

标签: c++ design-patterns

想象一下,有一个名为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(),这显然是相同的。

然而,这并不是一个合适的解决方案,而且“外人”肯定不清楚为什么有addChildrawAddChild方法。 我的逻辑是否存在问题,如果是,我该如何解决这个问题呢?或者我的解决方案已经很好了吗?

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

我会测试矢量是否已包含元素(可能使用set而不是vector)

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

答案 2 :(得分: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);
}