[geloest] Instanz der Singleton bei Beenden freigeben

Alles rund um die Programmierung mit Qt
Antworten
ColonelMoW
Beiträge: 30
Registriert: 15. April 2008 16:24

[geloest] Instanz der Singleton bei Beenden freigeben

Beitrag von ColonelMoW »

Hi!

Ich schreibe gerade eine Singleton-Klasse und mache mir Gedanken darueber, wann die eine Instanz wieder geloescht wird.

Hier mal die Klasse:

Code: Alles auswählen

class ConfigSingleton : public QObject
{
   Q_OBJECT
public:
   static ConfigSingleton* getInstance(void)
   {
      mutex.lock();
      if(!pInstance_)
      {
         pInstance_ = new ConfigSingleton(FILENAME);
      }
      mutex.unlock();
      return pInstance_;
   }
   
   ~ConfigSingleton(){qDebug() << "test";}
   ....

private:
   ConfigSingleton(const QString &filename, QObject *parent = 0);
   static ConfigSingleton *pInstance_;
   static QMutex mutex;
};

Wenn ich nun getInstance() aufrufe wird beim ersten Mal eine Instanz erzeugt und mir ein Pointer darauf zurueckgegeben. Diese Instanz liegt ja jetzt auf dem Heap.
Wie kann ich bei Programmende dafuer sorgen, dass diese Instanz geloescht wird?

Ich habe versucht das aboutToQuit() signal des QApplication-Objektes mit dem deleteLater() slot der Instanz zu verbinden. Leider sehe ich dann aber die test-ausgabe im Destruktor nicht. Heisst das nun, dass das Objekt nicht zerstoert wurde, oder kann Qt einfach nach dem emit von aboutToQuit() keine Debug Ausgaben mehr auf die Konsole bringen? Wenn ich denn deleteLater() manuell aufrufe, gehts.
Das aboutToQuit() erzeuge ich mit einem Button:

Code: Alles auswählen

QPushButton button("close");
QObject::connect( &button, SIGNAL(clicked()),
                            qApp, SLOT(quit()));
button.show();

Oder ist es besser der Instanz als Parent qApp zu geben? Dann sollte es doch auch geloescht werden, wenn die Applikation sich beendet. Jedoch kommt auch dann kein test-String aus dem Destruktor durch.

Hat schonmal jemand sowas implementiert und hat eine gute Loesung?

Col
Zuletzt geändert von ColonelMoW am 16. Mai 2008 12:10, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Entweder per qAddPostRoutine() oder sowas wie K_GLOBAL_STATIC oder Q_GLOBAL_STATIC (find grad die Seite mit der Beschreibung nicht). Ich würde qAddPostRoutine() verwenden - ist am einfachsten.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
ColonelMoW
Beiträge: 30
Registriert: 15. April 2008 16:24

Beitrag von ColonelMoW »

Danke dir! Funktioniert.
Fuer alle die es interessiert:
Ich habe meiner Singleton noch eine statische CleanUp-Funktion spendiert:

Code: Alles auswählen

public slots:
   static void cleanUp(void)
   {
      mutex.lock();
      if(pInstance_)
      {
         delete pInstance_;
         pInstance_ = NULL;
      }
      mutex.unlock();
   }
Im main uebergebe ich den Pointer auf die Funktion an qAddPostRoutine():

Code: Alles auswählen

   qAddPostRoutine(ConfigSingleton::cleanUp);
Es wird dann beim Beenden der Applikation automatisch die Instanz der Singleton geloescht.
Ein herzliches Dankeschoen an Christian!

Col
moviemax
Beiträge: 56
Registriert: 10. März 2008 09:49
Wohnort: München

Beitrag von moviemax »

Scheibst Du den in dein Singleton File auch was rein oder liest Du nur aus? Insgesammt finde ich es mit Kannonen auf spazen schossen.

Besser finde ich ein

Code: Alles auswählen

static create() {

   Q_ASSERT(! pInstance_);  // Achtung NOT! 
   
 pInstance_ = new ConfigSingleton;
 QString configFile = Settings::Instance()->configFile();
 mutex.lock(); 
       
      if(!pInstance_) 
      { 
         pInstance_.load(configFile); 
      } 
      mutex.unlock(); 
}
und dann ein ganz normales

Code: Alles auswählen


static ConfigSingleton* instance()
{
  Q_ASSERT(instance_)
   return instance_;
} 
beim Ändern der Einstellungen dann immer gleich mit

Code: Alles auswählen

 ConfigSingleton::save() 
{
   mutex_.lock();
   configs_ = data;  
   mutex_.unlock(); 
   
  // Write data to file 
  ... 
}
Am

Code: Alles auswählen

 

ConfigSingleton::~ConfigSingleton()
{
   // alles aufräumen 
   delete some pointers .... ;

}

im header file den die 3 constructoren private sezten 

gruß moviemax
Antworten