2013-06-04 4 views
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 должен быть обновлен и должен быть родитель обновляется; это создает бесконечный цикл.

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

Как вы можете видеть, это нехорошо. Мне удалось решить это, имея четыре метода для добавления вместо двух, но это несколько глупо. Дополнительные два метода объявлены private или protected, поэтому их нельзя вызывать другими. Вот оригинальный 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. Есть ли проблема с моей логикой, и если да, то как мне решить такую ​​проблему? Или мое решение уже хорошо?

ответ

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

Обратите внимание, что вы даже можете избавиться от почти бесполезного, оставив свой код одним методом вместо четырех. свататься! – slaphappy

+2

Я собирался предложить ваше решение, но я заметил, что «addParent» и «addChild» являются виртуальными. Что делать, если производный класс имеет особое поведение при добавлении дочернего элемента? Я бы предложил одну модификацию вашего ответа, а именно: сделать «addParent» и «addChild» не виртуальными, а при необходимости добавить «onParentAdded» и «onChildAdded» виртуальные методы, которые производные классы могут реализовать. –

+1

Я предполагаю, что 'Node' не предназначен для использования в полиморфном контексте и что спецификаторы' virtual' здесь не существуют по какой-либо конкретной причине. – slaphappy

0

я бы проверить, если вектор уже constains элемент (возможно, используя набор вместо вектора)

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

Примечание: Я получу сон, поэтому не совсем уверен, есть ли круговая ссылка, но вы получаете идею .... – dchhetri