2010-01-18 6 views
8

मैं दो वर्गों के साथ पेड़ जैसी संरचना को लागू करने की कोशिश कर रहा हूं: वृक्ष और नोड। समस्या यह है कि प्रत्येक वर्ग से मैं दूसरे वर्ग के एक समारोह को कॉल करना चाहता हूं, इसलिए सरल आगे की घोषणा पर्याप्त नहीं है। चलो एक उदाहरण देखें:शीर्षलेख फ़ाइलों के बीच चक्रीय निर्भरता

Tree.h:

#ifndef TREE_20100118 
#define TREE_20100118 

#include <vector> 
#include "Node.h" 

class Tree 
{ 
    int counter_; 
    std::vector<Node> nodes_; 

public: 

    Tree() : counter_(0) {} 

    void start() { 
     for (int i=0; i<3; ++i) { 
      Node node(this, i); 
      this->nodes_.push_back(node); 
     } 
     nodes_[0].hi(); // calling a function of Node 
    } 

    void incCnt() { 
     ++counter_; 
    } 

    void decCnt() { 
     --counter_; 
    } 

}; 

#endif /* TREE_20100118 */ 

Node.h:

#ifndef NODE_20100118 
#define NODE_20100118 

#include <iostream> 
//#include "Tree.h" 

class Tree; // compile error without this 

class Node 
{ 
    Tree * tree_; 
    int id_; 

public: 

    Node(Tree * tree, int id) : tree_(tree), id_(id) 
    { 
//  tree_->incCnt(); // trying to call a function of Tree 
    } 

    ~Node() { 
//  tree_->decCnt(); // problem here and in the constructor 
    } 

    void hi() { 
     std::cout << "hi (" << id_ << ")" << endl; 
    } 

}; 

#endif /* NODE_20100118 */ 

कॉलिंग ट्री:

#include "Tree.h" 
... 
Tree t; 
t.start(); 

समस्या को समझाने के लिए यह एक साधारण उदाहरण है। तो मैं जो चाहता हूं वह नोड ऑब्जेक्ट से पेड़ के एक समारोह को बुला रहा है।

अद्यतन # 1: उत्तर के लिए धन्यवाद। मैंने जावा में समस्या को हल करने की कोशिश की, यानी प्रति वर्ग केवल एक फ़ाइल का उपयोग कर। ऐसा लगता है कि मुझे .cpp और .h फ़ाइलों को अलग करना शुरू करना होगा ...

अद्यतन # 2: नीचे दिए गए संकेतों के बाद, मैंने पूरा समाधान भी चिपकाया। धन्यवाद, समस्या हल हो गई।

उत्तर

5

हेडर में, आगे सदस्य कार्यों की घोषणा:

class Node 
{ 
    Tree * tree_; 
    int id_; 

public: 
    Node(Tree * tree, int id); 
    ~Node(); 
    void hi(); 
}; 

एक अलग .cpp फ़ाइल है कि सभी आवश्यक हेडर में, उन्हें परिभाषित:

#include "Tree.h" 
#include "Node.h" 

Node::Node(Tree * tree, int id) : tree_(tree), id_(id) 
{ 
    tree_->incCnt(); 
} 

Node::~Node() 
{ 
    tree_->decCnt(); 
} 

etc 

यह भी की प्रभाव पड़ता है अपने हेडर को पठनीय रखने के लिए, इसलिए एक नज़र में कक्षा के इंटरफ़ेस को देखना आसान है।

0

क्या आप एक .cxx फ़ाइल में निर्माता/विनाशक निकायों के अलावा कर सकते हैं? आप वहाँ Tree.h शामिल कर सकते हैं।

1

Tree की परिभाषा Node की परिभाषा की आवश्यकता है, लेकिन दूसरी तरफ नहीं, इसलिए आपकी अगली घोषणा सही है।

आपको बस इतना करना किसी भी कार्य करता है कि Node वर्ग शरीर से Tree की एक पूरी परिभाषा की आवश्यकता होती है और उन्हें एक .cpp फ़ाइल में लागू जहां दोनों वर्गों का पूरा परिभाषाओं दायरे में हैं की परिभाषा निकाल दिया जाता है है।

2

संकेतों के बाद, यहां पूरा समाधान है।

Tree.h:

#ifndef TREE_20100118 
#define TREE_20100118 

#include "Node.h" 
#include <vector> 

class Tree 
{ 
    int counter_; 
    std::vector<Node> nodes_; 

public: 

    Tree(); 
    void start(); 
    void incCnt(); 
    void decCnt(); 
}; 

#endif /* TREE_20100118 */ 

Tree.cpp:

#include "Tree.h" 
#include "Node.h" 

Tree::Tree() : counter_(0) {} 

void Tree::start() 
{ 
    for (int i=0; i<3; ++i) { 
     Node node(this, i); 
     this->nodes_.push_back(node); 
    } 
    nodes_[0].hi(); // calling a function of Node 
} 

void Tree::incCnt() { 
    ++counter_; 
} 

void Tree::decCnt() { 
    --counter_; 
} 

नोड।ज:

#ifndef NODE_20100118 
#define NODE_20100118 

class Tree; 

class Node 
{ 
    Tree * tree_; 
    int id_; 

public: 

    Node(Tree * tree, int id); 
    ~Node(); 
    void hi(); 
}; 

#endif /* NODE_20100118 */ 

Node.cpp:

#include "Node.h" 
#include "Tree.h" 

#include <iostream> 

Node::Node(Tree * tree, int id) : tree_(tree), id_(id) 
{ 
    tree_->incCnt(); // calling a function of Tree 
} 

Node::~Node() { 
    tree_->decCnt(); 
} 

void Node::hi() { 
    std::cout << "hi (" << id_ << ")" << std::endl; 
}