2011-12-03 32 views
0

林創建我自己的雙向鏈表程序(我知道有一個列表庫)。我有我的main.cc只是我的主要功能,提供了一個菜單,選擇我的程序的各種選項,並調用正確的功能/對象。然後,我有3個不同的頭文件包含類文件,1是我的雙向鏈表函數的一般文件,另一個是將一般的DLL函數轉換爲隊列函數,最後一個是將DLL函數轉換爲堆棧函數。C++錯誤與模板的朋友類和

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:error:expected unqualified- ID之前「<」令牌 DLLstack.h:11:14:錯誤:預期標識符之前「<」令牌

以及我在兩個棧和隊列類「未在此範圍中聲明」 LST對象

雙鏈接list.h:141:2:錯誤:「下一步」,並沒有在這個範圍內聲明

有更多的錯誤,但我認爲日這些都是造成重大問題,我需要先解決這些問題才能繼續。

如果你想知道我編程在Ajuta IDE在Ubuntu

+0

是DoublyLinkedList模板?如果是這樣,爲什麼你要這樣聲明:DoublyLinkedList qlst; ? – selalerer

+0

這種氣味的不良做功課......還有,你擔心在30一個錯誤之前,先解決其他29來避免這些創建編譯器混淆。 – Walter

回答

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成員函數被調用(一旦你固定的把它叫做isEmpty錯別字)。

DoublyLinkedList::searchdelete,delete DLLNode<T>(tmp)應該只是delete tmp。您還需要修復了在節點中的指針上刪除一個的兩側,並返回T型(大概i)的值,並修復環路的行爲因此它實際上搜索正確的節點(因爲它是,它遍歷到最後,然後刪除空指針,結果它什麼都不做)。

最後,~DLLQueue試圖調用DoublyLinkedList::clear不存在。你應該實現這個或者DoublyLinkedList(或者兩者)的析構函數。事實上,該列表是內存泄漏。它也應該有一個拷貝構造函數和賦值操作符(如果你不希望這個類是可複製的,只需聲明爲私有)。

而且,包括警衛,你不應該使用保留的名稱(以下劃線開頭,如_DLLQUEUE_H_)。你也不應該把using namespace std;放在你的頭文件中;頭文件的用戶可能不希望全局命名空間受到污染。

+0

當我點擊添加類文件時,Anjuta會自動爲這些名稱做這些名稱。 –

+0

倒不如改變他們,或使IDE產生的法律名稱如果可能的話。否則,名稱可能與庫標題中使用的名稱衝突。 –

+0

你想我轉貼我的代碼,我改變了它按照你的,好位了對方的建議步驟 –

1

你的朋友聲明更改爲

template <class U> friend class DLLNode; 

而且分號在這裏失蹤

class DLLQueue 
{ 
    friend <class T> class DoublyLinkedList 
    friend <class T> class DLLNode 
0
  1. 不要寫自己的列表,堆棧或隊列。改爲使用std::dequestd::stackstd::queue適配器。
  2. 永遠不要在標題中做using namespace std
  3. 您的所有朋友聲明使用錯誤的語法。它應該是template <typename T> friend class X;(或class而不是typename)。此外,標識符區分大小寫,​​和DLLstack是兩個完全不同的東西。
  4. 您的課程在複製時無法正常工作。
  5. 請勿投入整數,請改爲使用std::exception的適當子類。
  6. 您不在成員變量定義中使用模板參數。

我沒有看到任何更多的主要問題,但我可能會錯過所有指針的東西。

+0

我真希望我能使用std ::隊列棧等等,什麼錯誤使用空間std?什麼你的意思是抄襲?我的老師明確告訴我們扔整數,並通過論證你的意思是的? –

+0

@WillGunn:一切是錯誤的'使用命名空間std',尤其是在頭部。按值傳遞變量時發生複製。複製時,您的類將導致雙重刪除。是的,是模板參數。 –

+0

重新:'const int的EMPTY_LIST = 1;'在頭違反一個定義規則。不,它不會 - 常量除非聲明爲'extern',否則具有內部連接。 –