2013-09-30 215 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