Allgemeine Frage - Global verfügbare Funktionen

Alles rund um die Programmierung mit Qt
Antworten
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Allgemeine Frage - Global verfügbare Funktionen

Beitrag von suamikim »

Hallo zusammen,

ich bin gerade dabei mein 1. etwas größeres Qt-Projekt zu schustern.

Dabei bin ich gerade auf folgende Frage gestoßen:

Ich hab ein MainWindow, welches eigentlich nichts enthält, außer das automatisch erzeugte centralWidget und ein von mir eingefügtes leeres QGridLayout.

Das ganze ist gewissermaßen wie ein Wizard aufgebaut, wo jede Seite anders aussieht. Jede Seite ist nun eine eigene von QWidget abgeleitete Klasse und wird je nach Bedarf im MainWindow angezeigt.

Das ganze funktioniert soweit ganz gut. Auch die Kommunikation ist über die parentWidget()-Funktion bzw. signals & slots kein Problem.

Jetzt würde ich aber gerne die eine oder andere Funktion für jede Klasse in meinem Projekt zugänglich machen.
In C++/MFC hab ich das bisher zB. immer so gemacht, dass ich die App-Klasse mittels extern überall bekannt mache. So konnte ich auf die public-Funktionen im App von überall zugreifen...

Danke, mfg

mike
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Wie wäre es mit einen Inteface das alle deine Widgets implementieren müssen?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

QT macht es aehnlich wie die MFC .,..

du erstellt doch normal dein QApplication Object oder ?

In jeder stelle deines codes, nachdem das QApplication object erstellt wurde kommst mit qApp (makro) drauf, man muss nur <QApplication> einbinden.

prinzipiell solltest das aber nur hernehmen, wenn es wirklich um applications spezifische daten (Verwaltung) geht ....

besser fuer eigene Dinge mit aehnlichem verhalten: Schau dir das Singleton (Designpatterns) an !

weiterhin kannst genau so "globale" funktionen nutzen ... einfach die signatur in nem header deklarieren, und in ner cpp definieren.
In deinen qobjecten brauchst dann nur die header includieren. Mit klassen geht das aehnlich.

Ciao ...
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Beitrag von suamikim »

@AuE:
Ein Interface ist nicht wirklich das, was ich suche. Mit einem Interface müsste wieder jede Klasse die Methoden selbst implementieren und genau das will ich ja vermeiden.

@RHBaum:
1) Das QApplication-Object wird normal erstellt. Den Code dafür hat mir der Qt Creator automatisch geliefert (main.cpp):

Code: Alles auswählen

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  return a.exec();
}
Wo könnte ich jetzt meine Methoden, die später dann über qApp zugänglich sind definieren und deklarieren? Ich hab ja kein eigenes Header- & Cpp-File für QApplication?

2) Singleton sieht Interessant aus, wäre aber aus meinem Verständnis (durchs ganz kurze einlesen) auch nicht dass, was ich suche (ein wenig "Overkill").

3) Genau so werde ich das wohl umsetzen.
Hab mir 2 Files dafür gemacht (globalDefinitions.h & globalDefinitions.cpp). Falls es mal jemanden Interessiert, hier ein kurzer Bsp-Code:

globalDefinitions.h:

Code: Alles auswählen

#ifndef GLOBALDEFINITIONS_H
#define GLOBALDEFINITIONS_H

#include <QString.h>

extern QString testFunction();

#endif // GLOBALDEFINITIONS_H
globalDefintions.cpp:

Code: Alles auswählen

#include "globalDefinitions.h"

extern QString testFunction()
{
  return "test text";
}
Jetzt kann man in jedem File, in dem man die Funktionen braucht einfach globalDefinitions.h einbinden und kann auf die Funktionen zugreifen. Gefällt mir für ein paar "triviale" Funktionen, die man überall mal wieder braucht ganz gut...

danke, mfg
dikilroy
Beiträge: 7
Registriert: 14. Januar 2009 22:08

Beitrag von dikilroy »

Hi,

einzige Kritik an der genutzten Möglichkeit ist, dass es nicht objektorientiert ist.
Aus Designgründen würde ich Dir ebenfalls entweder das Singelton Pattern oder das Static Konzept empfehlen.

Hier ein Beispiel für das Singelton Pattern (in einer Singlethreaded Umgebung):

Code: Alles auswählen

#include <QString>
class MyTest{
private:
   static MyTest *instance=NULL;
   
   MyTest(){}
   ~MyTest() { delete instance; }
public:
   static MyTest *getInstance(){
      if(NULL == instance){
         instance = new MyTest();
      }
      return instance;
   }  

   QString testString() { return QString("Hallo Welt");}
}

...
{
   // Verwendung im Code:
   QString lala = MyTest::getInstance()->testString();
}
Ich verwende das Singelton häufig für DB Geschichten, oder für Configurationen die Systemweit gelten sollen.

Handelt es sich um reine Funktionen, die also nicht auf systemweite Daten zugreifen sollen, sondern die ihre Daten über Parameter erhalten oder selbst ermitteln, kannst Du auch das Static Konzept verwenden.

Hier ein Beispiel:

Code: Alles auswählen

#include <QString>
class MyTest{
private:
   MyTest(){}
   ~MyTest(){}
public:
   static QString testString() { return QString("Hallo Welt");}
}

...
{
   // Verwendung im Code:
   QString lala = MyTest::testString();
}
Gott sei Dank hast Du in C/C++ alle Freiheiten der Welt ... kannst Dir aber auch in den Fuß schiessen ;)

Grüße
André
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Beitrag von suamikim »

Danke schön für die Anregungen.

Wenn ich genau darüber nachdenke wäre das Singleton-Pattern wohl doch etwas für mich, da ich in meinem aktuellen Projekt mit Datenbanken schongliere ;)

Sehe ich das richtig, dass ich in der Singleton-Klasse zB. alle Methoden fürs Datenbank-Handling (Verbindung aufbauen, Daten holen, Daten bearbeiten usw.) bereitstellen könnte und alle anderen Klassen dann auf diese Methoden zugreifen könnten?

Hört sich durchaus elegant an ;)
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

suamikim hat geschrieben:@AuE:
Ein Interface ist nicht wirklich das, was ich suche. Mit einem Interface müsste wieder jede Klasse die Methoden selbst implementieren und genau das will ich ja vermeiden.
Nicht wenn du sie nicht pure virtual machst.

Alternativ: Spräche etwas gegen statische Methoden?
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Beitrag von suamikim »

pfid hat geschrieben:Nicht wenn du sie nicht pure virtual machst.
Ok, so würds funktionieren...
pfid hat geschrieben:Alternativ: Spräche etwas gegen statische Methoden?
Bis vor 5 Minuten nicht ;)
Mittlerweile denke ich wirklich, dass Singleton der richtige Ansatz für mich ist. So kann ich in einer Klasse, die von überall erreichbar ist meine ganze Datenbank-Verwaltung kapseln. Das finde ich soweit ganz nett und werde mich daran wohl mal versuchen.

danke, mfg
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

einzige Kritik an der genutzten Möglichkeit ist, dass es nicht objektorientiert ist.
nen Singleton wuerd ich nehmen, wenn du wirklich ein "Object" zu definieren kannst ... also sowas wie ein globalen Logger, ein globales drucker Object .. etc, was intern auch noch verwaltungs informationen führt. Siehe Datenkapselung / Objektorientierung.

Hasst Du aber keinerlei "informationen" sprich sinnvolle member an deinem Object, erstellst du das Object nur wegens seines selbst wegen .... ist das nen schlechter ansatz ....
die weiterfuehrende alternative dazu waere die funktionen (wenn es bei einem object ned um member geht, kann es nur auf die methoden der klasse ankommen) statisch zu machen, dass man gar ned erst eine instanz anlegen muss.
und was sind statische methoden ??? nix anderes als globale funktionen hinter den namespace einer klasse versteckt. dann kannst auch gleich globale funktionen nehmen und die ordnungsgemaess in nen namespace packen.

Globale funktionen sind nicht boese, im Gegenteil, manchmal sinnvoll, sinnvoller als Leere instanzen, die nur der objectorientierung wegens erzeugt wurden.

auch in der welt der objectorientierung werden die ausgiebig genutzt ... oder was glaubt ihr was externe operatoren sind ... oder was die stl in vielen Faellen macht, schaut doch mal stl::min<> oder vieles in <functional> an ....

Wie gesagt, Singleton (Object Instanz) sollt man nehmen, wenn hinter der Instanz auch sinvolle Daten stehen. Ansonsten nimm funktionen

Interfaces ist nen Aehnliches thema ....
nen interface / Vererbung allgemein macht Sinn, wenn du zur Laufzeit die mehrere Implementationen deinen Anwendern (die Klassen die damit arbeiten) übergibst, ohne das die das mitbekommen (müssen).

Also zu deutsch, hasst du eine InterfaceKlasse IF und du hast nicht die Absicht, hinter einem Zeiger p auf IF jemals Instanzen unterschiedlicher Implementationsklassen laufen zu lassen, ist deine Anwendung der Polymorphie fragwuerdig , wahrscheinlich sogar unnötig und damit inperformant ...

Ciao ...
Zuletzt geändert von RHBaum am 12. November 2009 14:03, insgesamt 2-mal geändert.
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Beitrag von suamikim »

Mhm, genau darum wollte ich zuerst kein Singleton nehmen ("Overkill").

Ursprünglich wollte ich hauptsächlich Funktionen kapseln, die keine Daten beherbergen, sondern einfach irgendwas ausgeben (zB. einen bestimmten Text zu einer bestimmten Zahl).

Nachdem ich aber nun gerade meine ganzen Datenbank-Sachen kapsle war der Singleton-Vorschlag doch recht willkommen.

Denke genau in dieser Umgebung macht das ganze durchaus recht viel Sinn...
dikilroy
Beiträge: 7
Registriert: 14. Januar 2009 22:08

Beitrag von dikilroy »

suamikim hat geschrieben:Sehe ich das richtig, dass ich in der Singleton-Klasse zB. alle Methoden fürs Datenbank-Handling (Verbindung aufbauen, Daten holen, Daten bearbeiten usw.) bereitstellen könnte und alle anderen Klassen dann auf diese Methoden zugreifen könnten?
Ja, siehst Du richtig!
Eigentlich müsste ich Dich im Kontext von Qt auf die Qt DB-Klassen verweisen. Ich kenne die aber weniger, und nutze eher eigene bzw. andere.
Eigene DB-Klassen zu bauen braucht einiges an Gehirnschmalz und Geduld! Bei Fragen kannst Du mich gerne an PN'en ;)


Grüße
André
suamikim
Beiträge: 59
Registriert: 1. November 2009 15:58

Beitrag von suamikim »

Naja, meinen eigenen DB Treiber will ich mir nicht zusammenbauen. Ich benutze schon die Qt-Klassen, jedoch brauche ich doch einige Funktionen oefter und diese hab ich mir nun im Singleton gekapselt...

danke, mfg
Antworten