Seite 1 von 1
QSharedPointer
Verfasst: 12. Juli 2012 17:31
von DBGTMaster
Hallo,
folgender Code:
Code: Alles auswählen
typedef QSharedPointer<Database> DB;
...
...
DB t = DatabasePool::getConnection();
DB v = DatabasePool::getConnection();
Bei jedem Aufruf von getConnection wird ein QSharedPointer zurückgegeben, in diesem Fall zeigen beide QSharedPointer auf dem selben Pointer, wobei bei jedem getConnection aufruf ein eigenes QSharedObjekt erzeugt wird:
Code: Alles auswählen
DB DatabasePool::getConnection() {
return QSharedPointer<DB>(ptr);
}
Problem ist nun, nach Ende der Methode wird versucht, der Pointer 2x zu zerstören, ich will diesen aber nur 1x zerstören...
Lösung wäre, ich gebe jedes mal das selbe QSharedPointer Objekt zurück... Aber hier wieder ist das Problem, wenn ich das QSharedObjekt in der Klasse "DatabasePool" zwischenspeichere, wird der Pointer nie zerstört, da eben die DatabasePool Klasse auch den QSharedPointer hält...
Was kann ich tun?
lG
Re: QSharedPointer
Verfasst: 12. Juli 2012 18:33
von franzf
Das kann nur schief gehen. Die Methode gibt jedes mal einen komplett unabhängigen shared_ptr zurück, so dass natürlich viele den Pointer töten wollen. SharedPoii´nter machen aber nur dann Sinn, wenn ALLE SharedPointer, die sich um den selben Zeiger kümmern, auch alle gemeinsam zählen.
Lösung:
* Entweder ptr direkt selber als QSharedPointer deklarieren
* komplett auf Smart-pointer verzichten, und jemandem die Verantwortung übertragen.
// sry, das am Ende hab ich nicht mehr geselen...
Wann soll denn deiner Meingung nach der Zeiger dann zerstört werden? Wenn kein Benutzer außerhalb mehr eine Referenz darauf hält?
Re: QSharedPointer
Verfasst: 12. Juli 2012 20:34
von DBGTMaster
franzf hat geschrieben:Wann soll denn deiner Meingung nach der Zeiger dann zerstört werden? Wenn kein Benutzer außerhalb mehr eine Referenz darauf hält?
Ganz genau das benötige ich... Und ich hätte gedacht, das tut QSharedPointer auch, aber leider nicht, wie ich festgestellt habe

..
Gibts alternativen??
lG
Re: QSharedPointer
Verfasst: 12. Juli 2012 20:45
von Christian81
Abgesehen davon dass ich nicht glaube das es kompiliert - es sollte doch sicherlich 'return QSharedPointer<Database>(ptr)' heissen, oder?
Doch - es macht genau was Du sagst - erzeuge ein Objekt vom Typ QSharedPointer und gib es zurück und wenn der RefCount genau dieses Objektes 0 ist dann zerstöre das Objekt.
Du solltest ptr direkt als QSharedPointer<> ablegen.
Re: QSharedPointer
Verfasst: 13. Juli 2012 08:57
von DBGTMaster
Christian81 hat geschrieben:Du solltest ptr direkt als QSharedPointer<> ablegen.
Sorry, aber ich versteh nicht, was du mit dieser Aussage sagen willst???
Re: QSharedPointer
Verfasst: 13. Juli 2012 18:36
von Christian81
ptr ist doch (trotz der nicht vorhandenen Kennzeichnung per Notation oder ähnliches) hoffentlich ein Member von DatabasePool. Also mach dort nen QSharedPointer draus.
Re: QSharedPointer
Verfasst: 13. Juli 2012 20:42
von DBGTMaster
Christian81 hat geschrieben:ptr ist doch (trotz der nicht vorhandenen Kennzeichnung per Notation oder ähnliches) hoffentlich ein Member von DatabasePool. Also mach dort nen QSharedPointer draus.
Nein, das kann ich nicht tun. Die Klasse DatabasePool ist eine statische Klasse, und wenn ich dort als Member mein QSharedObjekt ablege, so lebt dieses auch so lange, wie das Programm läuft.
Wenn ich meinen QSharedPointer als member ablege, so muss ptr bereits zerstört werden, sobald noch ein SharedPointer auf ptr verweist, nämlich der, des QDatabasePool...
Aber ich denke, hier werde ich wohl einen eigenen SharedPointer schreiben müssen??
// Edit:
Wenn ich die Doku richtig verstanden habe, so kann ich im DatabasePool den Pointer als QWeakPointer ablegen, und daraus jedes mal bei der getConnection() Methode als QSharedPointer zurückgeben??
Re: QSharedPointer
Verfasst: 13. Juli 2012 21:15
von Christian81
Was willst Du überhaupt erreichen? Ich sehe keinen Grund warum hier ein QSharedPointer nötig wäre...
Und sag mir bitte nicht dass 'ptr' ein globaler statischer Pointer ist!
Re: QSharedPointer
Verfasst: 16. Juli 2012 10:25
von DBGTMaster
Christian81 hat geschrieben:Was willst Du überhaupt erreichen? Ich sehe keinen Grund warum hier ein QSharedPointer nötig wäre...
Und sag mir bitte nicht dass 'ptr' ein globaler statischer Pointer ist!
Doch, es ist ein globaler statischer Pointer

....
Nein, Scherz bei Seite, ... Mir fehlt gerade die Zeit, das ganze etwas zu erklären...
Aber hier mein Lösungsweg, hier wird der Destruktor nur mehr 1x aufgerufen:
Code: Alles auswählen
class Test {
public:
~Test() {
qDebug("destroy");
}
};
void test() {
QWeakPointer<Test> weak = QWeakPointer<Test>( QSharedPointer<Test>(new Test) );
QSharedPointer<Test> a = weak.toStrongRef();
QSharedPointer<Test> b = weak.toStrongRef();
QSharedPointer<Test> c = weak.toStrongRef();
QSharedPointer<Test> d = weak.toStrongRef();
}
Re: QSharedPointer
Verfasst: 16. Juli 2012 10:33
von franzf
Ja, aber dein ptr wird DIREKT NACH der Erstellung des weak wieder zerstört (temporärer SharedPointer...).
Wenn du mir nicht glaubst:
Code: Alles auswählen
#include <QtCore/QDebug>
#include <QtCore/QSharedPointer>
#include <QtCore/QWeakPointer>
class Test {
public:
~Test() {
qDebug("destroy");
}
};
int main() {
QWeakPointer<Test> weak = QWeakPointer<Test>( QSharedPointer<Test>(new Test) );
qDebug() << "Vor toStrongRef";
QSharedPointer<Test> a = weak.toStrongRef();
QSharedPointer<Test> b = weak.toStrongRef();
QSharedPointer<Test> c = weak.toStrongRef();
QSharedPointer<Test> d = weak.toStrongRef();
qDebug() << "Nach toStrongRef";
}
Du kannst auch a.isNull() oder weak.isNull() aufrufen - gibt immer true zurück.
Du wirst dir einen eigenen sharedptr schreiben dürfen, der bei genau einer Referenz schon zerstört (derjenigen statischen) und nicht erst bei count==0.