[英]Friend classes need to include or forward declare c++?
在嘗試使用隊列構建二叉樹時,我一直在與錯誤作斗爭。 問題是哪些類應該包含哪些文件以及如何從其他類中引用對象? 我將我的文件放入 IDE,試圖找出問題所在,結果如下。 目前我的問題是在 Queue.h 文件中,treePtr“沒有命名類型”。 你可以在這里看到這個問題的演變這個問題與其他帖子不同,因為這兩個類是友元類。 這就帶來了循環依賴的問題。 我嘗試了包含文件和前向聲明的各種組合,但一種組合會導致一種類型的問題,另一種會產生不同的錯誤。
這是主類:
#include <cstdlib>
#include "Tree.cpp"
using namespace std;
int main() {
Tree tree;
tree.addTreeNode(5);
return 0;
}
這是 Queue.h:
#ifndef QUEUE_H_
#define QUEUE_H_
class Tree; //Was instructed to put this here
class Queue {
friend class Tree;
private:
typedef struct node {
Tree::treePtr treeNode; //Here is the problem
node* next;
}* nodePtr;
nodePtr head;
nodePtr current;
public:
Queue();
virtual ~Queue();
void push(Tree::treePtr t); //Here is the problem
int pop();
void print();
};
#endif /* QUEUE_H_ */
這是 Tree.h:
#ifndef TREE_H_
#define TREE_H_
#include "Queue.h" //Was instructed to put this here
class Tree {
friend class Queue;
private:
Queue q; //Edit: Most likely problem since Queue and Tree are friends
typedef struct tree {
int data;
tree* left;
tree* right;
}* treePtr;
treePtr root;
int numNodes;
public:
Tree();
virtual ~Tree();
void addTreeNode(int integer);
};
#endif /* TREE_H_ */
這是 tree.cpp
#include <cstdlib>
#include <iostream>
#include "Tree.h"
using namespace std;
Tree::Tree() {
root = NULL;
numNodes = 0;
}
void Tree::addTreeNode(int integer) {
numNodes++;
treePtr t = new tree;
t->left = NULL;
t->right = NULL;
t->data = integer;
cout << "add root\n";
root = t;
q.push(t); //This is a problem
q.print();
}
Tree::~Tree() {
// TODO Auto-generated destructor stub
}
您必須分別編譯Tree.cpp
和(我想您有一個) Queue.cpp
,而不是在main.cpp
中包含Tree.cpp
。
前向聲明適用於友元類,即使您這樣做也是循環的。
將#include "Tree.h"
放在Queue.cpp
文件中,讓編譯器看到完整的聲明。
在main.cpp
只需放入#include " Tree.h"
。
為了獲得最終的可執行鏈接,所有生成的目標文件main.o(bj)
、 Tree.o(bj)
和Queue.o(bj)
。
另請參閱[為什么我不應該包含 cpp 文件而是使用標題?]請。
正如我現在注意到的,您的實際問題是,您無法從前向聲明的類/結構訪問嵌套類/結構,因為您需要從Queue
訪問treePtr
( treePtr
應該更好地命名為TreeNode
或類似的 BTW)。
在這種情況下,您不能將treePtr
私有嵌套類型,它必須是公開可見的。
一種可行的方法是將treePtr
放在namespace internal_
,這表明它不打算在 API 之外使用。
另一種可行的方法是使Queue
成為一個模板類,它接受任何類型的tree
或其他類型的節點。 既然看不到任何用例,為什么Queue
需要了解tree
的內部規范(除了像復制 aso 之類的瑣碎事情之外),實際上沒有必要將Queue
設為friend
類。
我最好的猜測是,問題在於,由於類 Queue 和 Tree 是朋友,並且 Tree 有一個 Queue 的實例作為數據成員,因此在嘗試包含文件和轉發聲明時會出現一些沖突。 通過與 Queue 共享數據成員,Tree 類與 Queue 類共享了一個 Queue 對象的實例化,因此有一些不明顯的初始共享正在進行。 @πάντα ῥεῖ 建議將 Queue 設為模板類,以便它可以接受任何類型的對象,而不必與 Tree 耦合(這樣做是為了讓 Queue 類知道如何處理 treePtr 對象)。 使 Queue 成為模板類解決了這個問題,因為現在 Tree 類可以有一個 Queue 的實例,而且我可以將 treePtr 類型的對象傳遞給 Queue,而 Queue 事先不知道關於 Tree 類的任何信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.