2011-12-03 8 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前:「<」トークン

だけでなく、両方のスタックとキュークラスは、「このスコープ内で宣言されていなかった」での私のLSTオブジェクト

前に予想識別子:11:14:エラー

二重リンク-list.h:2:141エラー:「次へ」はこのスコープで宣言されていなかった

そこに多くの誤りがありますが、私は目を考えますeseは大きな問題を引き起こしており、私はこれらを最初に修正して続ける必要があります。 Ubuntuの

あなたが思っているならば、私はAjuta IDEでプログラミングしています

+0

DoublyLinkedListはテンプレートですか?もしそうなら、なぜあなたは次のように宣言しますか?DoublyLinkedList qlst; ? – selalerer

+0

これはうまくやっていない宿題のにおいがします...また、30のエラーのうちの1つを心配する前に、最初に他のものを解決して、これらのコンパイラに対して混乱を避けてください。 – Walter

答えて

2
friend <class T> class DoublyLinkedList 

が欠落しています

template <class U> friend class DoublyLinkedList; 

または

friend class DoublyLinkedList<T>; 

実際の友人である必要がどのインスタンスに依存します。他の友人の宣言についても同様です。 DoublyLinkedListテンプレート、ないタイプであるため、

DoublyLinkedList qlst; 

DoublyLinkedList<T> qlst; 

でなければなりません。

ありますが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宣言するので、(あなたがisEmptyそれを呼び出す誤字を修正したら)それは他のクラスのconstメンバ関数から呼び出すことができます。

DoublyLinkedList::searchdeleteでは、delete DLLNode<T>(tmp)はちょうどdelete tmpである必要があります。また、削除されたノードの両端にあるノードのポインタを修正し、タイプT(おそらくi)の値を返し、正しいノードを実際に検索するようにループの動作を修正する必要があります、それは最後まで繰り返され、ヌルポインタが削除され、何もしないという結果になります)。

最後に、~DLLQueueは存在しないDoublyLinkedList::clearを呼び出しようとします。どちらか、またはDoublyLinkedList(またはその両方)のデストラクタを実装する必要があります。つまり、リストはメモリリークです。また、コピーコンストラクタと代入演算子(クラスをコピー可能にしたくない場合はprivateと宣言してください)も必要です。

また、インクルードガードとして予約名(アンダースコアで始まる、_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;(またはtypenameの代わりにclass)である必要があります。また、識別子は大文字と小文字を区別します。​​とDLLstackは全く異なる2つのものです。
  4. あなたのクラスはコピーでは正しく動作しません。
  5. intをスローしないで、代わりにstd::exceptionという適切なサブクラスを使用してください。
  6. メンバー変数定義でテンプレート引数を使用しません。

これ以上の大きな問題はありませんが、私はすべてのポインタに何か不足している可能性があります。

+0

私は本当にstd :: queue stack etc ...を使うことができたらいいと思っています。コピーすることを意味しますか?私の先生は具体的にintsを投げるように私たちに言った、そして引数であなたはのことを意味しますか? –

+0

@WillGunn:特にヘッダ内で 'namespace std'を使うのは間違っています。値を変数に渡すとコピーが行われます。クラスをコピーすると、ダブル削除が発生します。はい、がテンプレート引数です。 –

+0

Re: 'const int EMPTY_LIST = 1;'は、1つの定義ルールに違反します。いいえ、そうではありません - 定数は「extern」と宣言されていない限り、内部リンケージを持ちます。 –