Gespeicherten Zeiger mit get() zurückgeben



  • Hallo zusammen,

    ich sitze seit Stunden an Beispielcode in dem .get() im Zusammenhang mit Smart-Pointern genutzt wird. get() wird, laut Definition, genutzt um einen gespeicherten Zeiger zurückzugeben. Der Zweck von .get() wird mir allerdings nicht klarer dadurch.

    Im Beispielcode gibt es u.a diese Zeilen:

    // .h
    IDeckLinkScreenPreviewCallback*	GetCallback();
    private:
    std::unique_ptr<Emitter> m_emitter;
    ...
    
    // .cpp
    m_emitter = std::make_unique<Emitter>();
    QObject::connect(m_emitter.get(), &Emitter::valueChanged, this, &HandleEmit::setFrame, Qt::AutoConnection);
    
    IDeckLinkScreenPreviewCallback* HandleEmit::GetCallback() {
    	return m_emitFrame.get();
    }
    

    Warum wird .get() hier verwendet? Warum reicht es nicht eine normale Dereferenzierung?
    Hier habe ich dann auch noch gelesen das .get() eigentlich überflüssig ist.



  • QObject::connect() erwartet als ersten Parameter vermutlich einen Emitter*, auf den passt std::unique_ptr<Emitter> aber nicht. Du brauchst also eine Möglichkeit, an den Rohzeiger im smart_pointer zu kommen, und genau dazu ist std::uniqe_ptr<T>::get() da.

    Wenn du derefenzieren willst geht das auch mit &(*m_emitter), aber da halte ich get() für deutlich besser.



  • @DocShoe
    Das ist eine Erklärung mit der ich was anfangen kann. Danke!

    Genau, connect erwartet als ersten Parameter einen Raw-Pointer.



  • @makopo sagte in Gespeicherten Zeiger mit get() zurückgeben:

    Genau, connect erwartet als ersten Parameter einen Raw-Pointer.

    Nicht ganz, es muss ein Pointer auf eine Instanz sein, deren Klasse von der Basisklasse QObject abgeleitet ist. Deswegen funktioniert der unique_ptr nicht, er kann in der connect-Methode nicht dynamisch auf ein QObject Zeiger umgecastet werden.



  • Ich frag mich wieso hier ein unique_ptr verwendet wird. Da die Klasse Emitter von QObject abgeleitet sein sollte, reicht es zu ihr die aufrufende Klasse bei der Erzeugung vom Emitterobjekt als Parent mitzugeben. Der Parent kümmert sich dann ums wegräumen.



  • @Braunstein
    Bin mir nicht sicher ob ich dich richtig verstehe. Bin Neueinsteiger in C++ und Qt...
    Ja, dem Konstruktor Emitter() wird ein parent übergeben:

    Emitter::Emitter(QObject* parent)
    

    Meinst du sowas?

    Emitter m_emitter;
    m_emitter = new Emitter(parent);
    
    //Dtor
    Emitter::~Emitter() { 
        m_emitter->setParent(nullptr)
    };
    

    Edit: Code ergänzt.



  • @makopo
    Wenn du beim Erzeugen einen Parent mitgibst, was du mit:

    Emitter m_emitter;
    m_emitter = new Emitter(parent);
    

    ja tust, dann wird genau dieser Parent dafür sorgen, das deine Emitter-Instanz vom Destruktor des parent gelöscht wird. Du brauchst das also nicht selbst zu tun. Das ist bei allen Klassen so, die von QObject abgeleitet sind.



  • @Braunstein
    Danke, es fehlt aber der Zeiger auf die Emitter Instanz, oder?



  • Ja, es muß ein Zeiger sein:

    Emitter* m_emitter; // als Klassenmember deklariert
    
    // im Konstruktor
    m_emitter = new Emitter(parent);
    


  • Da hatte ich wohl kopiert ohne genau hinzuschauen.


Log in to reply