2013-09-30 272 views
0

以下代碼是來自C++數據結構文本的二叉樹實現。 我canot成功編譯代碼,得到一些錯誤消息。主要的錯誤行來自最後兩個代碼。如何解決這個問題? 我的IDE是CODE :: BLOCK 12.11。如何正確聲明嵌套類?

#include<iostream> 
#include<list> 
using namespace std; 

typedef int Elem; 
struct Node 
{ 
Elem elt; 
Node *par; 
Node *left; 
Node *right; 
Node():elt(),par(NULL),left(NULL),right(NULL){} 
}; 

class Position 
{ 
private: 
Node *v; 
public: 
Position(Node *_v=NULL):v(_v){} 
Elem &operator*(){return v->elt;} 
Position left()const{return Position(v->left);} 
Position right()const{return Position(v->right);} 
Position parent()const{return Position(v->par);} 
bool isRoot()const{return v->par==NULL;} 
bool isExternal()const{return v->left==NULL&&v->right==NULL;} 
friend class LinkedBinaryTree; 
}; 
typedef std::list<Position> PositionList; 

class LinkedBinaryTree 
{ 
protected: 
struct Node; //This line is by me, the text merely tell you "insert Node declaration here. . ." I don't know whether this line is correct or not. 
public: 
class Position; // Also by me, the text merely tell you "insert Position declaration here. . ." I don't know wwhether this line is correct or not. 
public: 
LinkedBinaryTree(); 
int size()const; 
bool empty()const; 
Position root()const; 
PositionList positions()const; 
void addRoot(); 
void expandeExternal(const Position& p); 
protected: 
void preorder(Node* v,PositionList& pl)const; 
private: 
Node* _root; 
int n; 
}; 


LinkedBinaryTree::LinkedBinaryTree():_root(NULL),n(0){} 
int LinkedBinaryTree::size()const{return n;} 
bool LinkedBinaryTree::empty()const{return size()==0;} 
LinkedBinaryTree::Position LinkedBinaryTree::root()const{Position(_root);} //canot compile successfully, this error messages is : C:\Users\user\Documents\aa\main.cpp|58|error: return type 'class LinkedBinaryTree::Position' is incomplete 
void LinkedBinaryTree::addRoot(){_root=new Node;n=1;} //canoot compile successfully, this error message is C:\Users\user\Documents\aa\main.cpp|59|error: invalid use of incomplete type 'struct LinkedBinaryTree::Node' 

有很多錯誤消息,我選擇其中之一來表示錯誤消息。

+0

閱讀錯誤消息,修復編譯錯誤.... –

+1

減少程序中的行數,直到產生問題的最小集合爲止。這個問題很可能會在當時盯着你。 – Floris

+0

Code :: blocks是一個IDE,不是編譯器。 – harper

回答

1

此:

class LinkedBinaryTree { 
protected: 
struct Node; 

被稱爲正向聲明(中Node)。它告訴編譯器有一個類型名稱,但它不是一個類的定義。除非定義可見,否則不能創建類型的實例。前向聲明不是一個定義。

如果你這樣寫:

class LinkedBinaryTree { 
protected: 
struct Node { /* ... */ }; 

那麼你就能夠創建一個Node

嵌套類的前向聲明通常適用於具有代碼相關類型時,或者您希望以特定方式排序聲明。

向前聲明是告訴編譯器有一個與該名稱的類型是有用的,所以它可以瞭解你的意圖在使用前:

class LinkedBinaryTree { 
protected: 
struct Node; 
void foo(Node*); 
struct Node { /* ... */ }; 

在這種情況下,指針不要求身體依賴性,所以當它看到foo的聲明時,該名稱足以滿足編譯器的要求。

另外請注意,您的向前聲明聲明在類的範圍NodePosition,所以編譯器需要它意味着void preorder(Node* v,PositionList& pl)const;使用類型本地類;例如void LinkedBinaryTree::preorder(LinkedBinaryTree::Node* v, LinkedBinaryTree::PositionList& pl)const;,而不是代碼示例中全局名稱空間中聲明的PositionNode

1

嵌套的聲明通常應發生在類中,像這樣:

#include<iostream> 
#include<list> 
using namespace std; 

class LinkedBinaryTree 
{ 
    protected: 
    typedef int Elem; 
    struct Node 
    { 
    Elem elt; 
    Node *par; 
    Node *left; 
    Node *right; 
    Node():elt(),par(NULL),left(NULL),right(NULL){} 
    }; 

    public: 
    class Position 
    { 
    private: 
    Node *v; 
    public: 
    Position(Node *_v=NULL):v(_v){} 
    Elem &operator*(){return v->elt;} 
    Position left()const{return Position(v->left);} 
    Position right()const{return Position(v->right);} 
    Position parent()const{return Position(v->par);} 
    bool isRoot()const{return v->par==NULL;} 
    bool isExternal()const{return v->left==NULL&&v->right==NULL;} 
    friend class LinkedBinaryTree; 
    }; 
    typedef std::list<Position> PositionList; 
    public: 
    LinkedBinaryTree(); 
    int size()const; 
    bool empty()const; 
    Position root()const; 
    PositionList positions()const; 
    void addRoot(); 
    void expandeExternal(const Position& p); 
    protected: 
    void preorder(Node* v,PositionList& pl)const; 
    private: 
    Node* _root; 
    int n; 
}; 


LinkedBinaryTree::LinkedBinaryTree():_root(NULL),n(0){} 
int LinkedBinaryTree::size()const{return n;} 
bool LinkedBinaryTree::empty()const{return size()==0;} 
LinkedBinaryTree::Position LinkedBinaryTree::root()const{Position(_root);} //canot compile successfully, this error messages is : C:\Users\user\Documents\aa\main.cpp|58|error: return type 'class LinkedBinaryTree::Position' is incomplete 
void LinkedBinaryTree::addRoot(){_root=new Node;n=1;} 
+0

此聲明有效。謝謝。爲什麼我不能在課堂外聲明和定義它們? – Makoto

+0

嵌套類的重點在於它們發生在另一個類中。因此,將它們定義在母類之外是沒有意義的。 – user2829635