模板友好类的C ++错误

时间:2011-12-03 10:26:56

标签: c++ compiler-errors

我正在创建自己的双链表项目(我知道有一个列表库)。我的main.cc只有我的main函数,它提供了一个菜单来为我的程序选择各种选项并调用正确的函数/对象。然后我有3个不同的头文件包含类文件,1是我的双链表函数的通用文件,另一个是将一般的DLL函数转换为队列函数,最后一个是将DLL函数转换为堆栈函数。

main.cc

#include <iostream>


#include "doubly-linked-list.h"
#include "DLLstack.h"
#include "DLLqueue.h"

using namespace std
int choice=0,choice2=0;

int main()
{
    int choice=0,choice2=0,i=0;
    DoublyLinkedList<int> lst;
    DLLstack stlist;
    while(1)
    {

        choice2=0;
        //ask user
        cout<<"\n1. Create Simple (Unsorted) List\n2. Create Sorted List\n";
        cout<<"3. Create LIFO Queue\n4. Create FIFO Queue(Stack)\n";
        cout<<"5. Exit Program\n";
        cout<<"Please choose an option\n";
        cin>>choice;

        while(choice==1)
        {

            //ask user 1.a
            cout<<"\n1. Enter integer for insertion at head of list\n2. Enter integer for insertion at tail of list\n";
            cout<<"3. Display and Delete integer at head\n4. Display and Delete integer at tail\n";
            cout<<"5. Search for integer in list and delete that node\n6.  Display Contents of list from head to tail in order\n7.  Exit\n";
            cout<<"Please choose an option\n";
            cin>>choice2;

            if(choice2==1)//1.1
            {cout<<"Enter integer to add to head\n";
                cin>>i;
                lst.addToDLLHead(i);
            }
            if(choice2==2)//1.2
            {
                cout<<"Enter integer to add to tail\n";
                cin>>i;
                lst.addToDLLTail(i);
            }
            if(choice2==3)//1.3
            { try{
                i=lst.deleteFromDLLHead ();
            } catch(int error_code)
                {
                    cerr<<"Error: "<<error_code<<endl;
                    switch(error_code)
                    {cout<<"Empty List\n";
                            return(1);
                    }
                }

                cout<<"The deleted int was "<<i<<endl;
            }
            if(choice2==4)//1.4
            { try{
                i=lst.deleteFromDLLTail ();
            } catch(int error_code)
                {
                    cerr<<"Error: "<<error_code<<endl;
                    switch(error_code)
                    {case 1:
                        cout<<"Empty List\n";
                            return(1);
                    }
                }
                cout<<"The deleted int was "<<i<<endl;
            }
            if(choice2==5)//1.5
            {
                cout<<"Enter Integer to search for and delete"<<endl;
                cin>>i;
                try{
                    lst.searchdelete (i);
                } catch(int error_code)
                {
                    cerr<<"Error: "<<error_code<<endl;
                    switch(error_code)
                    {cout<<"Empty List\n";
                            return(1);
                    }
                }
            }
            if(choice2==6)
            {lst.printlist ();}
            if(choice2==7) choice=0;
        }





        while(choice==2)
        {
            //ask user 2.b
            cout<<"\n1. Enter integer for sorted insertion(increasing order) into list\n2. Display and delete integer if present in list\n";
            cout<<"3. Display contents of sorted list of integers, in increasing order\n";
            cout<<"4. Exit program\n";
            cout<<"Please choose an option\n";
            cin>>choice2;

            if(choice2==1)//2.1
            {cout<<"Enter integer to add to the sorted list"<<endl;
                cin>>i;
                lst.addSorted (i);
            }
            if(choice2==2)
            {
                cout<<"Enter Integer to search for and delete"<<endl;
                cin>>i;
                try{
                    lst.searchdelete (i);
                } catch(int error_code)
                {
                    cerr<<"Error: "<<error_code<<endl;
                    switch(error_code)
                    {cout<<"Empty List\n";
                            return(1);
                    }
                }
            }
            if(choice2==3)
            {lst.printlist ();}
            if(choice2=4)
            {choice=0;}
        }






        while(choice==3)
        {
            cout<<"\n1. ENQUEUE\n2. DEQUEUE\n";
            cout<<"3. Print QUEUE\n";
            cout<<"4. Exit program\n";
            cout<<"Please choose an option\n";
            cin>>choice2;
            DLLQueue.qlst;

            if(choice2==1)
            {
                cout<<"Enter number to place in Queue"<<endl;
                cin>>i;
                qlst.enqueue(i);}
            if(choice2=2)
            {try{qlst.dequeue();
            } catch(int error_code)
                {
                    cerr<<"Error: "<<error_code<<endl;
                    switch(error_code)
                    {cout<<"Empty List\n";
                            return(1);
                    }
                }
            }
            if(choice2=3)
            {lst.printlist ();}
            if(choice2=4)
            {choice=0;}


        }

            while(choice==4)
            {
                cout<<"\n1. Push\n2. Pop\n";
                cout<<"3. Print STACK\n";
                cout<<"4. Exit program\n";
                cout<<"Please choose an option\n";
                cin>>choice2;
                if(choice2==1)
                {cout<<"Please enter value to place in stack"<<endl;
                    cin>>i;
                    stlst.push(i);
                }
                if(choice2==2)
                {stlst.pop();}
                if(choice2==3)
                {lst.printlist ();}
                if(choice2==4)
                {choice=0;}
            }






        } //original while

        return 0;
    }

双向链接-list.h

#ifndef DOUBLY_LINKED_LIST
#define DOUBLY_LINKED_LIST
#include <iostream>
using namespace std;

const int EMPTY_LIST=1;
template<class T>
class DLLNode
{
    friend class DoublyLinkedList;
    friend class DLLQueue;
    friend class DLLstack;
public:
    DLLNode(){next=prev=NULL;}
    DLLNode(const T& el, DLLNode *n=NULL, DLLNode *p=NULL)
{info=el;
    next=n;
    prev=p;
}
T info;
DLLNode<T> *next, *prev;
protected:
//T info;
//DLLNode<T> *next, *prev;
private:

};

template<class T>
class DoublyLinkedList
{
    friend class DLLQueue;
    friend class DLLstack;
public:
    DoublyLinkedList() {head=tail=NULL;} //good
    void addToDLLTail(const T&); //good
    T deleteFromDLLTail(); //good
    T isDLLEmpty() {return (head==NULL);} //good
    void addToDLLHead(const T&); //added
    T deleteFromDLLHead(); //added
    void deleteDLLNode(const T&); //added
    bool isInList(const T&) const; //added
    void addSorted(const T&); //added
    void printlist(); //added
    T searchdelete(const T&);


protected:

private:
DLLNode<T> *head, *tail;
};

template<class T>
T DoublyLinkedList<T>::deleteFromDLLTail(){
    if(head!=NULL){
        T el=tail->info;
        if(head==tail){
            delete tail;
            head=tail=NULL;
        }
        return el;
    }
    else throw(EMPTY_LIST);
}

template<class T>
void DoublyLinkedList<T>::addToDLLTail(const T& el) {
    if(tail!=NULL){
        tail=new DLLNode<T>(el,NULL,tail);
        tail->prev->next=tail;
    }
    else head=tail= new DLLNode<T>(el);
}

template<class T>
void DoublyLinkedList<T>::addToDLLHead (const T& el) {
    head = new DLLNode<T>(el,head);
    if(tail==NULL) tail=head;
}

template<class T>
T DoublyLinkedList<T>::deleteFromDLLHead (){
    if(head!=NULL)
    {
        int el=head->info;
        DLLNode<T> *tmp=head;
        if(head==tail)
        {head=tail=NULL;}
        else{head=head->next;}
        delete tmp;
        return(el);
        }
    else throw(EMPTY_LIST);
}

template<class T>
void DoublyLinkedList<T>::deleteDLLNode(const T& el) {  
if(head!=NULL){
   if(head==tail&&el==head->info) {
       delete head;
       head=tail=NULL;
   }
   else if(el==head->info){
       DLLNode<T> *tmp=head;
       head=head->next;
       head->prev=NULL;
       delete tmp;
   }
   else {
       DLLNode<T> *pred, *tmp;
       for(tmp=head->next;tmp!=NULL && tmp->info!=el;tmp=tmp->next);
       if(tmp!=NULL){
           pred=tmp->prev;
           pred->next=tmp->next;
           pred->next->prev=pred;

       if(tmp==tail) {tail=tail->prev;}
           delete tmp;
       }
   }
}
else throw(EMPTY_LIST);
}

template<class T>
bool DoublyLinkedList<T>::isInList(const T& el) const {
    DLLNode<T> *tmp;
    for(tmp=head;tmp!=NULL&&tmp->info !=el; tmp=tmp->next);
    return (tmp !=NULL);
}

template<class T>
void DoublyLinkedList<T>::addSorted(const T& i) {
    DLLNode<T> *tmp, *nxt;
    for(tmp=head;tmp->info<i;tmp=tmp->next);
    nxt=tmp->next;
    tmp->next= new DLLNode<T> (i,nxt,tmp);
    next->prev=tmp->next;
    delete tmp;
    delete nxt;
}

template<class T>
void DoublyLinkedList<T>::printlist() {
    DLLNode<T> *tmp;
    if(head!=NULL){
    for(tmp=head;tmp->next!=NULL;tmp=tmp->next){
        cout<<tmp->info<<endl;
    }
    }
}

template<class T>
T DoublyLinkedList<T>::searchdelete(const T& i)
{ DLLNode<T> *tmp;
    for(;tmp->info!=i&&tmp!=NULL;tmp=tmp->next){}
        delete DLLNode<T> (tmp);
    return(cout<<"Value Deleted from List\n");
}



#endif // DOUBLY_LINKED_LIST

DLLstack.h

#ifndef _DLLSTACK_H_
#define _DLLSTACK_H_
#include <iostream>
using namespace std;

#include "doubly-linked-list.h"
class DLLstack
{
    friend class<class T> DoublyLinkedList;
    friend class<class T> DLLNode;
public:
    DLLstack(){};
    bool isEmpty() const
{return lst.isEmpty();}
    void clear()
{
    while(!list.isEmpty()){
        lst.deleteFromDLLHead();}
}
int pop()
{return (lst.deleteFromHead();}
void push(const int& el);
{lst.addToDLLHead (el);}
int topEl()
{
    int topelement;
    topelement=lst.deleteFromDLLHead ();
    lst.addToDLLHead (topelement);
    return(topelement);
}
protected:

private:
DoublyLinkedList stlst;
};

#endif // _DLLSTACK_H_

DLLqueue.h

#ifndef _DLLQUEUE_H_
#define _DLLQUEUE_H_
#include <iostream>
using namespace std;
#include "doubly-linked-list.h"
template<class T>
class DLLQueue
{
    friend <class T> class DoublyLinkedList
    friend <class T> class DLLNode
public:

DLLQueue(){};
bool isEmpty() const
{ return lst.isEmpty();}
void enqueue(const T& el)
{ lst.addToDLLTail (el);}
T dequeue()
{ return {lst.deleteFromDLLHead ();}
T firstEl()
{
    T front_el;
    front_el=lst.deleteFromDLLHead ();
    lst.addToDLLHead (front_el);
    return(front_el);
}
~DLLQueue() {clear();}
protected:

private:
DoublyLinkedList qlst;
};

#endif // _DLLQUEUE_H_

现在我得到30个错误,但我的主要问题(我认为)是我在我的DLLqueue.h文件和DLLstack.h文件中说我的朋友函数声明 DLLqueue.h:11:9:错误:在'&lt;'标记之前预期的unqualified-id DLLstack.h:11:14:错误:'&lt;'标记

之前的预期标识符

以及堆栈和队列类中的第一个对象“未在此范围内声明”

doubly-linked-list.h:141:2:错误:'next'未在此范围内声明

还有更多错误,但我认为这些问题导致了主要问题,我需要先解决这些问题才能继续。

如果您想知道我在Ubuntu的Ajuta IDE中进行编程

3 个答案:

答案 0 :(得分:2)

friend <class T> class DoublyLinkedList

应该是

template <class U> friend class DoublyLinkedList;

friend class DoublyLinkedList<T>;

取决于实际需要成为朋友的实例;同样也适用于其他朋友的声明。

DoublyLinkedList qlst;

应该是

DoublyLinkedList<T> qlst;

因为DoublyLinkedList是模板,而不是类型。

DLLStack::push中的函数体之前不应该有分号:

void push(const int& el);
{lst.addToDLLHead (el);}

(中有一个不受欢迎的)DLLstack::pop不匹配:

{return (lst.deleteFromDLLHead();}

{中不需要的DLLQueue::deque

{ return {lst.deleteFromDLLHead ();}

存在各种拼写错误(例如声明成员stlst并将其称为lstlist) - 编译器错误会直接指向这些错误。

DoublyLinkedList::isDLLEmpty需要声明const,因此可以从其他类的const成员函数调用它(一旦你修复了调用它的拼写错误{{1} }})。

isEmpty中,DoublyLinkedList::searchdelete应为delete DLLNode<T>(tmp)。您还需要修复已删除的节点两侧的节点中的指针,并返回类型delete tmp的值(可能是T),并修复循环的行为,以便它实际搜索对于正确的节点(因为它,它迭代到最后,然后删除空指针,结果它什么都不做)。

最后,i尝试调用不存在的~DLLQueue。您应该实现它,或者DoublyLinkedList::clear(或两者)的析构函数。实际上,列表是内存泄漏。它还应该有一个复制构造函数和赋值运算符(如果你不希望该类是可复制的,则简单地声明为私有)。

此外,您不应该使用保留名称(以下划线开头,例如DoublyLinkedList)作为包含警戒。您也不应将_DLLQUEUE_H_放在头文件中;头文件的用户可能不希望全局命名空间被污染。

答案 1 :(得分:1)

将您的朋友声明更改为

template <class U> friend class DLLNode;

此处也缺少分号

class DLLQueue
{
    friend <class T> class DoublyLinkedList
    friend <class T> class DLLNode

答案 2 :(得分:0)

  1. 不要编写自己的列表,堆栈或队列。请将std::deque改为使用std::stackstd::queue适配器。
  2. 请勿在标题中执行using namespace std
  3. 您的所有朋友声明都使用错误的语法。它应该是template <typename T> friend class X;(或class而不是typename)。此外,标识符区分大小写,DLLStackDLLstack是两个完全不同的内容。
  4. 您的课程无法正常复制。
  5. 不要抛出整数,而是使用std::exception的正确子类。
  6. 您不在成员变量定义中使用模板参数。
  7. 我没有看到任何重大问题,但我可能会在所有指针中丢失一些东西。