Rückgabewert: Referenz



  • Aknayirp schrieb:

    Das ist richtig, nur ich dachte ich muss eine Referenz zurückgeben, aber entries ist doch ein Pointer.

    Stimmt. Und mit "*" wird dieser Pointer dereferenziert. Den erhaltenen Wert kannst du dann als Referenz zurückgeben.



  • daddy_felix schrieb:

    Aknayirp schrieb:

    Das ist richtig, nur ich dachte ich muss eine Referenz zurückgeben, aber entries ist doch ein Pointer.

    Stimmt. Und mit "*" wird dieser Pointer dereferenziert. Den erhaltenen Wert kannst du dann als Referenz zurückgeben.

    Cool, das macht Sinn. Danke:D



  • Nathan schrieb:

    Returne einfach *(entries + index).

    Man könnte auch die Kurzschreibweise entries[index] statt *(entries + index) verwenden 😉



  • hustbaer schrieb:

    Nathan schrieb:

    Returne einfach *(entries + index).

    Man könnte auch die Kurzschreibweise entries[index] statt *(entries + index) verwenden 😉

    das hat Nathan in seinem Beitrag unter "BTW" auch gleich erwähnt 😉



  • Hey Leutz, hab ne neue Frage hehehe,
    diesmal geht es um Exceptions. Der Code war noch derselbe von vorhin, diesmal soll aber in der Operator Funktion gecheckt werden, ob auf einen gültigen Bereich zugegriffen wird.

    Dafür sollte ich erst eine neue Klasse (XOutOfBounds) erstellen und diese sollte von Exception ableiten. XOutOfBounds hat als Fkt. nur einen Konstruktur mit dem Parameter "const char* msg" und msg soll an den Konstruktor von Exception weitergegeben werden.

    Wenn jetzt auf einen Index zugegriffen, was falsch ist, soll eine Exception auf XOutBounds geworfen werden.
    Ich habe jetzt einiges von "Try" und "Catch" und "Throw" gelesen, aber hier ist jetzt keine Rede davon.

    Auf jeden Fall, bekomme ich diese Fehlermeldung, wenn ich das so kompiliere:

    "error C2011: 'XOutOfBounds': 'class' Typneudefinition"
    "Siehe Deklaration von 'XOutOfBounds'"

    So sieht auf jeden Fall der Code aus:

    template <class T, unsigned int N> T& CArray<T,N>::operator[](unsigned int index)
    {
      if(index>= N || index<0)
        throw XOutOfBounds();
      return entries[index];
    }
    
    /*DAS HABE ICH IN EINE EIGENE HEADER GESCHRIEBEN, WEIL DIESE DATEI SPÄTER NOCH BENUTZT WERDEN MUSS(KLASSE)*/
    
    #include<exception>
    #include<iostream>
    
    using namespace std; 
    
    class XOutOfBounds : public exception
    {
      public:
        XOutOfBounds(const char* msg) : exception(msg){};
    };
    

    Sry, wegen der Länge, aber kann es irgendwie nicht einfacher erklären. Ich will keine Anforderung an euch stellen, aber wäre toll wenn nicht direkt die Lösung gepostet wird, sondern lieber auf den Fehler hingewiesen wird und ich versuch das selbst zu lösen.
    Achja und die Fehlermeldung sagt ja aus, das was mit der Klasse bzw. der Deklaration nicht stimmt, aber ich seh den Fehler nicht.
    Das ist mein einziger Code für Exception und die main habe ich bekommen, wird getestet mit den UnitTests.

    Bin natürlich dankbar für jede Hilfe!



  • Include Guards?

    Und brauchst du wirklich den Header iostream bei deiner Exceptionklasse?

    Edit: Exception Tutorial: http://magazin.c-plusplus.net/artikel/Exception-Handling



  • Jau wollte grad meinen Beitra editieren, weil hab grad selber gemerkt, dass die guards fehlen... Und nope hast recht iostream wird nicht benötigt.
    Auf jeden Fall kommt nun eine andere Fehlermeldung. Wahrscheinlich weil der Konstruktor einen Parameter erwartet und ich keinen eingesetzt habe. Aber weiß nicht was genau da rein soll...



  • Aknayirp schrieb:

    Auf jeden Fall kommt nun eine andere Fehlermeldung. Wahrscheinlich weil der Konstruktor einen Parameter erwartet und ich keinen eingesetzt habe. Aber weiß nicht was genau da rein soll...

    throw XOutOfBounds("XOutOfBoundsException");
    

    😉

    Aber noch ein wirklicher Fehler in Deinem Code: new[] impliziert delete[] . Also den D'tor entsprechend ändern.



  • Jau, danke das hat gepasst.

    Aber noch ein wirklicher Fehler in Deinem Code: new[] impliziert delete[] . Also den D'tor entsprechend ändern.

    Komischerweise kompiliert er alles und die Test sind auch alle richtig. Deshalb verstehe ich nicht was du mit D´tor meinst.



  • Wenn du den Speicher, den du mit new[] angeforder hast, vie delete freigibst, ist das Verhalten undefiniert.
    Undefiniert heißt: "Your program's behavior is undefined -- you have no way of knowing what will happen...That means compilers may generate code to do whatever they like: reformat your disk, send suggestive email to your boss, fax source code to your competitors, whatever." -- Scott Meyers, "Effective C++"
    Es ist pures Glück, dass das bei dir funktioniert.
    Gebe den Speicher mit delete[] frei und alles ist gut.
    Ein weiterer Grund, warum man nicht mit dynamischen Speicher manuell hantieren sollte, aber wenn das verlangt ist...
    Sicher, dass N ein Templateparameter sein muss?



  • Nathan schrieb:

    Wenn du den Speicher, den du mit new[] angeforder hast, vie delete freigibst, ist das Verhalten undefiniert.
    Undefiniert heißt: "Your program's behavior is undefined -- you have no way of knowing what will happen...That means compilers may generate code to do whatever they like: reformat your disk, send suggestive email to your boss, fax source code to your competitors, whatever." -- Scott Meyers, "Effective C++"
    Es ist pures Glück, dass das bei dir funktioniert.
    Gebe den Speicher mit delete[] frei und alles ist gut.
    Ein weiterer Grund, warum man nicht mit dynamischen Speicher manuell hantieren sollte, aber wenn das verlangt ist...
    Sicher, dass N ein Templateparameter sein muss?

    Jap, N muss ein Templateparameter sein. Aber ich muss doch den Speicher wieder freigeben? Beim erstellen des Objekts wird durch den Konstruktor doch Speicher reserviert und dieser muss doch am Ende wieder freigegeben werden. Und genau das passiert doch, deshalb verstehe ich das "Undefiniert" nicht. Ich verstehe ja was du meinst, das andere Daten gelöscht werden können, aber den Speicher den ich reserviere, den kann ich doch wieder freigeben, so wie ich das gemacht habe.

    EDIT: Habe gerade das im Internet gefunden => delete []entries. Ist das jetzt so richtig?



  • Aknayirp schrieb:

    EDIT: Habe gerade das im Internet gefunden => delete []entries. Ist das jetzt so richtig?

    Jupp.
    Und wahrscheinlich hast Du Dir jetzt auch gedacht, dass D'tor D[estruk]tor ist.



  • Ja, das hat Sinn gemacht:D
    Vielen Dank nochmal an alle für die ganze Hilfe!



  • daddy_felix schrieb:

    hustbaer schrieb:

    Nathan schrieb:

    Returne einfach *(entries + index).

    Man könnte auch die Kurzschreibweise entries[index] statt *(entries + index) verwenden 😉

    das hat Nathan in seinem Beitrag unter "BTW" auch gleich erwähnt 😉

    *self-facepalm*

    Ich bin blind!
    Sorry @Nathan! 🙂



  • Furble Wurble schrieb:

    Aknayirp schrieb:

    EDIT: Habe gerade das im Internet gefunden => delete []entries. Ist das jetzt so richtig?

    Jupp.
    Und wahrscheinlich hast Du Dir jetzt auch gedacht, dass D'tor D[estruk]tor ist.

    Was, das heisst nicht Deletor? 😮 🤡



  • ...



  • Destruktor.



  • Devastat0r 😡



  • Destrutinator.



  • Hat zwar nichts direkt mit Referenzen zutun, aber ich schreibe das mal hier rein...

    Hab unter Ausnutzung des Singleton Prinzips die Klasse hier geschrieben aber ich bekomme eine Fehlermeldung. Wäre toll, wenn mir einer sagen könnte, was ich den übersehen bzw. falsch gemacht habe.

    //einmal die Deklaration in .h
    
    #ifndef _CDoubleHashing
    #define _CDoubleHashing
    
    #include <iostream>
    class CDoubleHashing
    {
    private:
      CDoubleHashing();
      CDoubleHashing(const CDoubleHashing& other);
      CDoubleHashing operator=(CDoubleHashing& other);
      static CDoubleHashing m_instanz;
    public:
      static CDoubleHashing& getInstance();
      unsigned int hash(unsigned int I, unsigned int J, unsigned int dict_size, unsigned int attempt);
    };
    
    #endif _CDoubleHashing
    
    //einmal in .cpp
    
    #include"CDoubleHashing.h"
    
    CDoubleHashing& CDoubleHashing::getInstance()
    {
      return m_instanz;
    }
    
    CDoubleHashing CDoubleHashing::m_instanz;
    
    unsigned int CDoubleHashing::hash(unsigned int I, unsigned int J, unsigned int dict_size, unsigned int attempt)
    {
      int x = 2/(I+J)*(I+J+1)+J;
    
      return ( x + attempt*(1+ ( x%(dict_size-2) ) ) ) % dict_size;
    }
    

    Bekomme ein "error LNK2019", habe danach gegooglet, hat mir aber herzlich wenig geholfen...

    MfG
    Aknayirp


Anmelden zum Antworten