2010-01-18 32 views
8

Tôi đang cố gắng triển khai cấu trúc giống cây với hai lớp: Cây và Nút. Vấn đề là từ mỗi lớp tôi muốn gọi một hàm của lớp khác, vì vậy khai báo đơn giản về phía trước là không đủ. Chúng ta hãy xem một ví dụ:phụ thuộc cyclic giữa các tệp tiêu đề

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 */ 

Calling Tree:

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

Đây chỉ là một ví dụ đơn giản để minh họa vấn đề. Vì vậy, những gì tôi muốn là gọi một chức năng của cây từ một đối tượng Node.

Cập nhật # 1: Cảm ơn câu trả lời. Tôi đã cố gắng giải quyết vấn đề như trong Java, tức là chỉ sử dụng một tệp cho mỗi lớp. Có vẻ như tôi sẽ phải bắt đầu tách các tệp .cpp và .h ...

Cập nhật # 2: Dưới đây, làm theo các gợi ý, tôi cũng đã dán giải pháp hoàn chỉnh. Cảm ơn, đã giải quyết được sự cố.

Trả lời

5

Trong các tiêu đề, chuyển tiếp tuyên bố các hàm thành viên:

class Node 
{ 
    Tree * tree_; 
    int id_; 

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

Trong một tập tin cpp riêng biệt mà bao gồm tất cả các tiêu đề bắt buộc định nghĩa chúng:

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

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

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

etc 

này cũng có tác dụng giữ cho tiêu đề của bạn dễ đọc, vì vậy rất dễ dàng để xem nhanh giao diện của lớp học.

0

Bạn có thể tạo cấu trúc hàm tạo/hủy trong tệp .cxx không? Bạn có thể bao gồm Tree.h ở đó.

1

Định nghĩa của Tree yêu cầu định nghĩa Node nhưng không phải theo cách khác xung quanh để khai báo chuyển tiếp của bạn là chính xác.

Tất cả những gì bạn phải làm là loại bỏ các định nghĩa của bất kỳ chức năng đòi hỏi một định nghĩa đầy đủ của Tree khỏi cơ thể Node lớp và thực hiện chúng trong một file .cpp nơi định nghĩa đầy đủ của cả hai lớp học nằm trong phạm vi.

2

Làm theo các gợi ý, đây là giải pháp hoàn chỉnh.

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

Node.h:

#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; 
} 
Các vấn đề liên quan