简体   繁体   中英

C++ overload operator []

I want to implement an indexing with [] for my deque class. I wrote my own class for it .. however, I get an error: "unexpected qualifier-id before '['token ...

maybe I did not quite understand how operator[] works, I can't use the usual indexing with [] for arrays, because I implemented a pointer structure for my deque class...

I divided my class into a .cpp and a .h file - here are the complete files , but maybe only the string& Deque::operator[](int i) { method in the .cpp file is interesting...

.cpp:

#include <iostream>
#include <cstring>
#include <cassert>
#include "ueb3.h"
using namespace std;



enum FunktionsTyp { beenden, pushb, pushf, popb, popf, iter,/*istElement,*/ausgeben};

void menue() {
cout<<endl;
cout<< pushb << ": am Ende einfuegen  " <<endl
    << pushf << ": am Anfang einfuegen  " <<endl
    << popb  << ": letztes Element entfernen  " <<endl
    << popf  << ": erstes Element entfernen  "  <<endl
    //<< istElement <<": Indexweiser Zugriff " <<endl
    << iter <<": Ueber Deque iterieren " <<endl
    << ausgeben << ": Werte ausgeben  " <<endl
    << beenden << ": beenden " <<endl <<endl;
    cout <<"Bitte Zahl eingeben: " ;
}


//"ITERATOR" DEQUE EINMAL DURCHLAUFEN VORNE BIS HINTEN
void Deque::ausgeben()
    {
        if (isEmpty()){
            cout << "Deque ist leer"<<endl;
            return ;
        }
        else
        {
            cout <<"AUSGEGEBEN:\t ";
            Node * tmp = front;
            //cout <<tmp->data<<", ";
            cout <<tmp->getData()<<", ";
            //tmp = tmp->next;
            tmp = tmp->getNext();
            while(tmp != 0){            
                //cout<<tmp->data;  
                cout <<tmp->getData()<<", ";
                //tmp=tmp->next;
                tmp = tmp->getNext();
            }   
            cout<<"\n";     
        }
    }

void iterieren(Deque& d);


int main()
{          
    Deque q;    
    int funktion;    
    string t;
    string s;

    do {
    menue(); 
    cin >> funktion;
    cout <<endl;

    switch (funktion) {
    case pushb : cout << "Wert eingeben: "; cin >> t;
    q.push_back(t);
    break;
    case pushf: cout << "Wert eingeben: "; cin >> t;
    q.push_front(t);
    break;      
    case popb : 
    if (q.isEmpty()) {
        cout <<"Deque ist leer!"<<endl;
        break;
    }
    s = q.pop_back();
    cout <<"Wert entfernt (vom Ende): " <<s <<endl;
    break;
    case popf : 
    if (q.isEmpty()) {
        cout <<"Deque ist leer!"<<endl;
        break;
    }
    s= q.pop_front();
    cout <<"Wert entfernt (vom Anfang): " <<s <<endl;
    break;
    /*case istElement:
    cout <<"Welches Indexelement soll gesucht werden? : "; 
    cin>>o; 
    q.[o];  ;
        */
    break;  
    case iter:
    iterieren(q);
    break;
    case ausgeben :
    q.ausgeben();   
    case beenden : 
    break;
    default : cout << "Falsche Funktion!\n";
    }
    } while (funktion != beenden);


    /*TESTEN DER OPERATOREN
    string aaa = "TEST\t";
    Node * ppn= new Node(aaa);
    cout <<ppn->getData()<<endl;

    Node * n = new Node("hallo");   
    Node p(n);
    cout<<p.getData()<<endl;

    Node * h = new Node("test222"); 

    Node * z = h;
    cout <<z->getData();

    bool same = h==z;
    cout <<"Node z und h gleich? " <<same<<endl;;

    bool same2 = h!=z;
    cout <<"Node z und h nicht gleich? " <<same2<<endl;



    Deque a ;
    a.push_front("erster Wert Deque1");
    Deque b;
    b.push_front("erster Wert Deque2 ");

    Deque c = a+b;
    c.ausgeben();
    Deque d = c+=a;
    d.ausgeben();


    */



return 0;       
}

  bool operator==(Node& a,Node& b) {
      Node * tmp  = &a;
      Node * tmp2 = &b;
      return ( tmp->getData() == tmp2->getData());
  }

    bool operator!=(Node& a,Node& b) {
      Node * tmp  = &a;
      Node * tmp2 = &b;
      return ( tmp->getData() != tmp2->getData());
  }

  Deque& Deque::operator+=(Deque& a) {
      if (this->getFront() == a.getFront()) {
          cout << "Abbruch. Gleiche Deques?"<<endl;
          return *this;
      }

      else{   
      int count1 =0;
      count1 = a.Size();      
      int sum= this->count += count1;     
      this->setSize(sum);

      Node * tmp = a.getFront();
      this->append_Node(tmp);
      this->rear = a.getRear();
  }

      return *this;  

  }

Deque& Deque::operator+(Deque& a){  
    *this += a;
    return *this;
}

/*
string& Deque::operator[](int i) {
    assert( i>=0 && i< this->Size()-1);
    int start = 0;
    string found ;
    if (this->isEmpty()){
                cout<<"Deque ist leer!" <<endl;

    }
    Node * tmp = this->getFront();
    bool gefunden = false;
    while (!gefunden && start < i) 
    {   
        if (start!=i) {         
        tmp = tmp->getNext();
        if (tmp == 0) {
            cout <<"Es existiert kein " << i<<".tes Element" <<endl;

        }
        start++;
    }   
    if ( start == i) {
        string * found = new String(tmp->getData());
        cout <<i << ".ter Wert: " <<found<<endl;
        gefunden = true;
        return * found;     
    }
    }
    return 0;
}
*/

    bool Deque::isEmpty()
    {       
        return count == 0 ? true : false;
    }


     Deque::iterator it;
    void iterieren(Deque& d){   
        if (d.isEmpty()) {
            cout <<"Deque leer!"<<endl;
            return;
        }
        for (Node *it = d.getFront(); it != 0; it = it->getNext()) {    
            cout << it->getData()<<", ";            
        }
        cout<<endl;
    }

.h file:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;


class Node
{   
private:
    string data="\0";
    Node* next=0;
    Node* prev=0;

public:

Node(){};



Node(string p){
    this->data = p;
}

//KOPIERKONSTRUKTOR MIT POINTER
Node(Node * n) {
    this->data = n->getData();
    this->next = n->getNext();
    this->prev = n->getPrev();

}

//KOPIERKONSTRUKTOR MIT REFERENZPARAMETER
Node(Node& n) {
    Node * tmp = &n;
    this->data = tmp->getData();
    this->next = tmp->getNext();
    this->prev = tmp->getPrev();
    delete tmp;
}

//ZUWEISUNGSOPERATOR(=)
Node& operator=(Node& n) {
    Node * tmp = &n;
    this->data = tmp->getData();
    this->next = tmp->getNext();
    this->prev = tmp->getPrev();
    return *this;
}



string getData(){
    return this->data;
}  

string getData() const{
    return this->data;
}  

void setData(string v) {
    this->data = v;
}

Node * getNext() {
    return this->next;
}

Node * getNext() const{
    return this->next;
}

Node * getPrev() {
    return this->prev;
}  


Node * getPrev() const {
    return this->prev;
}  


void setNext(Node * n) {
    this->next = n;
}

void setPrev(Node * n) {
    this->prev = n;
}    

};



class Deque
{  
private:
    Node* front;
    Node* rear;
    int count;

public:
    Deque()
    {
        front =0 ;
        rear =0;
        count = 0;
    }   

    typedef Node* iterator;


    //ELEMENT AM ANFANG HINZUFUEGEN
    void push_front(string element)
    {
        // Create a new node
        Node* tmp = new Node(element);
        //tmp->data = element;
        //tmp->next = 0;
        //tmp->prev = 0;

        if ( isEmpty() ) {
            // erstes Element hinzufuegen
            front = rear = tmp;
        }
        else {
            // Ganz vorne anhaengen und Pointer umbiegen
            //tmp->next = front;
            tmp->setNext(front);
            //front->prev = tmp;
            front->setPrev(tmp);
            front = tmp;
        }
        count++;
    }

    //ERSTES ELEMENT ENTFERNEN
    string pop_front()
    {
        if ( isEmpty() ) {          
             cout << "Deque ist leer" <<endl;

        }

        //  Wert aus erstem Knoten holen
        string ret = front->getData();

        // Ersten Knoten loeschen und Wert holen
        Node* tmp = front;
        if ( front->getNext() != 0 )
        {
            front = front->getNext();
            front->setPrev(0) ;
        }
        else
        {
            front = 0;
        }
        count--;
        delete tmp;

        return ret;
    }

    //ELEMENT AM ENDE HINZUFUEGEN
    void push_back(string element)
    {          
        // neuen Tmp Knoten erzeugen
        Node* tmp = new Node();
        //tmp->data = element;
        //tmp->next = 0;
        //tmp->prev = 0;

        tmp->setData(element);
        tmp->setNext(0);
        tmp->setPrev(0);

        if ( isEmpty() ) {           
            front = rear = tmp;
        }

        else {
            // hinten an Liste anhaengen, Pointer umbiegen
            //rear->next = tmp;
            rear->setNext(tmp);
            //tmp->prev = rear;
            tmp->setPrev(rear);
            rear = tmp;
        }

        count++;
    }

    void append_Node(Node * firstNode)
    {
        if (isEmpty()) {
            front = rear = firstNode;
        }

        else 
        {
            rear->setNext(firstNode);
            firstNode->setPrev(rear);
        }
    }

    //LETZTES ELEMENT ENTFERNEN
    string pop_back()
    {
        if ( isEmpty() ) {
             throw "Deque ist leer";

        }

        string ret = rear->getData();

        // letzten Knoten loeschen und Pointer umsetzen
        Node* tmp = rear;
        if ( rear->getPrev() != 0 )
        {
            rear = rear->getPrev();
            rear->setNext(0);
        }

        else
        {
            rear = 0;
        }
        count--;
        delete tmp;
        return ret;
    }


    //PEEK ERSTES ELEMENT
    string getFirst()    
    {          
        if ( isEmpty() )
            cout << "Deque ist leer"<<endl;
        return front->getData();
    }

    //PEEK LETZTES ELEMENT
    string getLast()
    {
        if ( isEmpty() )
             cout << "Deque ist leer"<<endl;
        return rear->getData();
    }

    //ANZAHL ELEMENTE IM DECK ZURUECKGEBEN
    int Size()
    {
        return count;
    }

    void setSize(int size){
        this->count = size;
    }

    //DECK LEER?
    bool isEmpty();


    Node * getFront() {
        return front;
    }

    Node * getRear() {
        return rear;
    }

    //"ITERATOR" DEQUE EINMAL DURCHLAUFEN VORNE BIS HINTEN
    //in der ueb3.cpp Datei implementiert
    void ausgeben();

    Deque& operator+=(Deque& a);

    Deque& operator+(Deque& a);

    void iterieren(Deque& d);


    //string& operator[]( int i);
};

Here is code of your operator[] that is compiled:

string& Deque::operator[](int i) {
        // You need to check whether i is in dequeue range, and, if not in range, throw an exception
    assert( i>=0 && i< this->Size()-1);
    int start = 0;
    string found ;
    if (this->isEmpty()){
                cout<<"Deque ist leer!" <<endl;

    }
    Node * tmp = this->getFront();
    bool gefunden = false;

    while (!gefunden && start < i)
    {
        // In this loop we will always find appropriate element
        if (start!=i) {
        tmp = tmp->getNext();
        if (tmp == 0) {
            cout <<"Es existiert kein " << i<<".tes Element" <<endl;

        }
        start++;
    }  
    if ( start == i) {
        break; // OK, we found one
        //string * found = new String(tmp->getData()); // It won't be compiled
        string * found = new string(tmp->getData());
        cout <<i << ".ter Wert: " <<found<<endl;
        gefunden = true;
        return * found;
    }
    }
        return tmp->getDataRef();
    //return 0; This string is buggy
}

I have also added function to the Node class. This one is needed to obtain data reference:

class Node {
...
std::string& getDataRef() {
        return this->data;
}
...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM