const Referenz als Zeiger ?



  • Hallo Leute,

    ich muss ein Objekt einer Klasse X übergeben:

    * ich bekomme das Objekt mit folgender signatur

    static const X & X::getX();
    

    * und soll es an diese Methode

    Y::benutzeObjektX(const X* x);
    

    übergeben.

    Oben das getx() liefert immer statisch eine Referenz auf ein 'neues' eigenes Objekt.
    Unten verlangt es ein const Zeiger auf das Objekt.
    Ich häng grad und bin ratlos?



  • Y::benutzeObjektX(&X::getX());
    

    Technisch sollte es so gehen, ob es sinnvoll ist, steht auf einem anderen Blatt.



  • Danke! Gesagt getan, funzt 👍

    Desweiteren ist die Klasse X um unique_pointer (als X_Ptr) erweitert, sodass möglichst X_Ptr genutzt werden soll:

    class X {
    
    private:
      // hide
      X();
      X(const X&);
      void operator=(const X&);
    
    public:
      Void clear();
    };
    
    class X_Ptr {
    
    public:
      // constructors
      X_Ptr();
    
      explicit X_Ptr(X* ptr)
        : _ptr(ptr)
      {
      }
    
      // move
      X_Ptr(X_Ptr&& other)
        : _ptr(other._ptr)
      {
        other._ptr = nullptr;
      }
    
      void operator=(X_Ptr&& other)
      {
        X* tmp = _ptr;
        _ptr = other._ptr;
        other._ptr = tmp;
      }
    
      // operators
      X& operator*()
      {
        return *_ptr;
      }
    
      const X& operator*() const
      {
        return *_ptr;
      }
    
      X* operator->()
      {
        return _ptr;
      }
    
      const X* operator->() const
      {
        return _ptr;
      }
    
      ~X_Ptr();
    
    private:
      // hide
      X_Ptr(const X_Ptr&);
      void operator=(const X_Ptr&);
    
      X* _ptr;
    };
    

    Nun habe ich wieder woanders eine Methode

    Z::benutzeRawPointer(const X* x)
    

    Zur verfügung habe ich aber:
    X_Ptr xptr;
    wie übergebe ich xptr an benutzeRawPointer(xptr) ?

    Fehler: no matching function for call to 'Z::benutzeRawPointer(X_Ptr)'



  • Mit den zur Verfügng stehenden Funktionen vielleicht so

    Z::benutzeRawPointer(&(*xptr));
    

    Welchen Sinn soll das haben? X_Ptr ist sicher kein unique_ptr.



  • Mal am Rande bemerkt:

    lespaul schrieb:

    class X_Ptr {
    
    public:
      // constructors
      X_Ptr();
    
      explicit X_Ptr(X* ptr)
        : _ptr(ptr)
      {
      }
    
      // move
      X_Ptr(X_Ptr&& other)
        : _ptr(other._ptr)
      {
        other._ptr = nullptr;
      }
    
      void operator=(X_Ptr&& other)
      {
        X* tmp = _ptr;
        _ptr = other._ptr;
        other._ptr = tmp;
      }
    
      // operators
      X& operator*()
      {
        return *_ptr;
      }
    
      const X& operator*() const
      {
        return *_ptr;
      }
    
      X* operator->()
      {
        return _ptr;
      }
    
      const X* operator->() const
      {
        return _ptr;
      }
    
      ~X_Ptr();
    
    private:
      // hide
      X_Ptr(const X_Ptr&);
      void operator=(const X_Ptr&);
    
      X* _ptr;
    };
    

    Das ist kein guter Move-Assignment-Operator. Man würde nicht erwarten, dass die Resource, die vom Ziel der Zuweisung gehalten wird, auf einmal in der Quelle landet. Die Quelle ist nicht notwendigerweise kurzlebig und könnte so eine Resource unerwartet lang am leben lassen. Mach es lieber so:

    void operator=(X_Ptr temp)
      {
        std::swap(this->_ptr, temp._ptr);
        // pass-by-value => temp wird hier automatisch zerstört
      }
    

    Aber ich würde auch nicht jedes Mal das Rad neuerfinden wollen. Du könntest gleich std::unique_ptr benutzen oder — falls Dir die Propagierung der const ness vom Zeiger zum Gezeigten wichtig ist — so eine Ptr-Klasse generisch machen. Bei unique ownership halte ich Deinen const ness-Ansatz für durchaus sinnvoll. std::vector macht das ja auch so. Ob man das dann noch „Ptr“ nennen sollte, ist eine andere Frage, über die man sich streiten kann.



  • manni66 schrieb:

    Welchen Sinn soll das haben?

    Ich habe es auch so bekommen. Ich nehme an, um vergessene delete zu meiden?

    manni66 schrieb:

    X_Ptr ist sicher kein unique_ptr.

    Ja kein echtes unique_ptr, aber ein "nachgebasteltes" oder nicht?



  • lespaul schrieb:

    manni66 schrieb:

    Welchen Sinn soll das haben?

    Ich habe es auch so bekommen. Ich nehme an, um vergessene delete zu meiden?

    Das kann unique_ptr nicht?

    lespaul schrieb:

    manni66 schrieb:

    X_Ptr ist sicher kein unique_ptr.

    Ja kein echtes unique_ptr, aber ein "nachgebasteltes" oder nicht?

    Ja, so gut dass du nicht vernünftig an den Pointer kommst.



  • X_Ptr(X_Ptr&& other)
        : _ptr(other._ptr)
      {
        other._ptr = nullptr;
      }
    

    Das ist doch der Move-Kopierkonstruktor. Aber was bedeuten die beiden Referenz-Zeichen "X_Ptr&& other" in der Parameterliste?

    Mit einem & wäre es ja eine Referenz, aber 2 ?



  • Mit 2 ist das eine RValue-Referenz. Sie bindet auf RValues, anstatt die LValue Referenz die auf LValues bindet.
    Und weil das eine RValue-Referenz ist, ist das der Movekonstruktor. Denn er nimmt nur Temporaries und das Ergebnis von std::move entgegen, während der Kopierkonstruktor LValues entgegennimmt.
    Das dient zur Unterscheidung, ob das Objekt bald zerstört ist und man ihm somit die Resourcen klauen kann, oder nicht.



  • Nun habe ich wieder woanders eine Methode

    Z::benutzePtrPointer(X & x) const
    

    Zur verfügung habe ich aber: X_Ptr xptr;

    wie übergebe ich xptr an benutzePtrPointer(xptr) ?

    Fehler: no matching function for call to 'Z::benutzePtrPointer(X_Ptr (&)()) const' x_ref.benutzePtrPointer(*xptr);



  • Na, du nutzt den Dereferenzierungsoperator wie bei normalen Pointern.



  • Nathan schrieb:

    Na, du nutzt den Dereferenzierungsoperator wie bei normalen Pointern.

    Hab ich ja schon, weswegen die Fehlermeldung kam..

    lespaul schrieb:

    x_ref.benutzePtrPointer(*xptr);



  • Der Fehlermeldung nach ist xptr kein X_Ptr sondern eine Funktion, die ein X_Ptr zurückgibt. Hast du xptr zufällig wie folgt definiert?

    X_Ptr xptr();
    

    EDIT: Nein, mit der Dereferenzierung passt die Fehlermeldung nicht mehr. Aber so etwas in der Richtung wird es sein.



  • LordJaxom schrieb:

    Hast du xptr zufällig wie folgt definiert?

    🤡 Ja, die Klammern hab ich doch glatt übersehen..
    Ich danke für diesen Hinweis 👍



  • Hallo Leute,
    ich habe eine Funktion welche eine const Referenz auf ein X_Ptr Objekt erhält.

    bool
    Z::calc_X_Ptr(const X_Ptr & local_xptr, double & local_DoubleRef)
    {
      // calc stuff!
      return true;
    }
    

    etwas drüber habe ich dann ein const X_Ptr Objekt:

    const X_Ptr x_ptr;
    

    Ich schaffe es nicht die Methode aufzurufen 😕

    myProg.cpp:210: Fehler: no matching function for call to 'Z::calc_X_Ptr(const X &, double&)'
    Z::calc_X_Ptr(x_ptr, doubleValue);
    ^



  • Du willst dem Compiler wohl ein X_Ptr für ein X vormachen.



  • manni66 schrieb:

    Du willst dem Compiler wohl ein X_Ptr für ein X vormachen.

    Ich dachte ich will ein X_Ptr als Referenz weitergeben?
    Ich habe ja ein:

    const X_Ptr x_ptr;
    

    und möchte dies einpflanzen in

    const X_Ptr & local_xptr
    


  • lespaul schrieb:

    Hallo Leute,
    ich habe eine Funktion welche eine const Referenz auf ein X_Ptr Objekt erhält.

    bool
    Z::calc_X_Ptr(const X_Ptr & local_xptr, double & local_DoubleRef)
    {
      // calc stuff!
      return true;
    }
    

    Der Compiler sagt aber was anderes. Und zwar

    Compiler-Fehlermeldung schrieb:

    Z::calc_X_Ptr(const X &, double&)



  • patrick246 schrieb:

    Der Compiler sagt aber was anderes. Und zwar

    Compiler-Fehlermeldung schrieb:

    Z::calc_X_Ptr(const X &, double&)

    Sorry

    Z::calc_X_Ptr(const X_Ptr &, double&)
    

    wäre richtig.



  • x_ptr ist kein X_Ptr, sondern ein X.


Anmelden zum Antworten