[gelöst] Objekt der Basisklasse als Parameter übergeben

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Bronski
Beiträge: 44
Registriert: 10. Oktober 2008 13:46

[gelöst] Objekt der Basisklasse als Parameter übergeben

Beitrag von Bronski »

Hallo.
Ich habe einige Zeit in C++ nichts mehr gemacht, so kann es sein das mir einige Basics entfallen sind.
Also seit mir bitte nicht böse wenn folgende Frage etwas dämlich ist.

Ich habe eine Klasse (Tdsa_orte_db) von QSqlDatabase abgeleitet.
Ich möchte nun im Konstruktor von Tdsa_orte_db eine Instanz von QSQLQuery erzeugen.
Dazu muß ich das Objekt der Basisklasse (also von QSQLDatabase) als Parameter übergeben.

Bei folgendem beschwert sich der MOC:

Code: Alles auswählen

 Tdsa_orte_db::Tdsa_orte_db(QString driver_name) :QSqlDatabase::QSqlDatabase(driver_name)
{

      SQL_get_all_location_names_ptr = new QSqlQuery(*this);//auch bei (QSQLDatabase) *this
      M_all_locations__names_ptr = new QSqlQueryModel(0);

}
Was mache ich falsch ?

Vielen Dank für eure Antworten.
Zuletzt geändert von Bronski am 17. August 2010 13:57, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Ableiten ist in diesem Fall sicher der falsche Weg. Wenn überhaupt möchtest du ein Member-Objekt vom Typ QSqlDatabase haben. Aber auch das kannst du dir sparen. QSqlDatabase speichert für dich die Verbindungen intern ab. Du kannst dir jederzeit die Verbindungen mit QSqlDatabase::database() holen, wenn du sie brauchst. Pass auf den Parameter "connectionName" auf, sollte alles in der Doku Beschrieben werden.

Zum Problem: Aus dem Codefetzen wird man nicht schlau :P Nur dass du Queries als Member anlegst, diese auch noch dynamisch allokierst. Beides unnötig, im schlimmsten Falle Kontraproduktiv.
Dein Basisinitialisierer ist außerdem falsch 1) in der Ausführung 2) der gewünschte Konstruktor ist für dich nicht erreichbar (schau in die Doku, gibt keinen mit QString als Parameter).
Bronski
Beiträge: 44
Registriert: 10. Oktober 2008 13:46

Beitrag von Bronski »

Erstmal:
Danke für die schnelle Antwort.

Also,die Idee ist folgende:
Ich möchte für jede Datenbankstruktur(jedes Datenmodell) eine Klasse haben.die sämtliche Zugriffe abhandelt
(Tdsa_orte_db) und sämtliche Ergebnismengen enthält. Dieser wollte ich die Verbindungsdaten gleich mitgeben. Da aber ein QSqlDatabase Objekt mehrere
Verbindungen beinhalten kann scheint es mir sinnvoll das anders zu abstrahieren.

Ich habe dies jetzt geändert und somit ist das Problem eigentlich gelöst.

Dennoch ist mir einiges nicht ganz klar:
1.Ich scheine mit der Übergabe von Parametern meine liebe Not zu haben.

Wenn ich meine Bücher richtig verstehe müsste die richtige Syntax folgende sein:
Tdsa_orte_db::Tdsa_orte_db(QString driver_name) :QSqlDatabase(driver_name)

oder etwa nicht ?

2. Der Konstruktor QSqlDatabase ( const QString & type ) ist protected.
Das heißt doch aber, dass er sich von den Konstruktoren und Methoden abgeleiteter Klassen hätte aufrufen
lassen müssen.

Wieso hat folgendes nicht funktioniert ?

Code: Alles auswählen


Tdsa_orte_db::Tdsa_orte_db(const QString driver_name)
{
 QSqlDatabase::QSqlDatabase(driver_name);
}
3.
Dies sind meine ersten Gehversuche, was die Datenbankfunktionen von Qt anbelangt.
Warum sollte man keine Queris als Member anlegen ?
Die Anwendung soll ein Frontend für eine MySql Datenbank werden.
Gibt es bei dem Design,dass man alle Zugriffe in eine Klasse packt gravierende Nachteile ?
Wie würde ein besseres Design aussehen ?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Bronski hat geschrieben:Ich möchte für jede Datenbankstruktur(jedes Datenmodell) eine Klasse haben.die sämtliche Zugriffe abhandelt
(Tdsa_orte_db) und sämtliche Ergebnismengen enthält. Dieser wollte ich die Verbindungsdaten gleich mitgeben. Da aber ein QSqlDatabase Objekt mehrere Verbindungen beinhalten kann scheint es mir sinnvoll das anders zu abstrahieren.
Ein QSqlDatabase-Objekt enthält GENAU EINE Verbindung! QSqlDatabase managed aber auch statische Member, in denen mehrere Verbindungen gespeichert werden. ->
typedef QHash<QString, QSqlDriverCreatorBase*> DriverDict;

Wenn du verhindern willst, dass niemand über QSqlDatabase::database() an deine Verbindung kommt, ist der Ansatz mit Erben vllt. zu vertreten. Dann solltest du aber private von QSqlDatabase erben, damit das Objekt von außen nicht als QSqlDatabase-Objekt verwendet werden kann, und somit dein Versuch schon im Ansatz fehlschlägt :P.

Zum Rest:
1) Wo ist da das Problem? die Übergabe des driver_name? Der Basisinitialisierer? Aber so schaut in jedemfall eine korrekte Basisinitialisierung mit einem non-default-Konstruktor aus.

2) Ja, sry, hab ich nicht gesehen dass der nur protected ist. Ja, wenn du erbst kannst du auf protected-Member zugreifen - auch auf den Konstruktor. Du willst aber dann den Konstruktor als Basisinitialisierer aufrufen.
Und wenn ein Code nicht kompiliert, ist es immer gut die Fehlermeldung zu lesen (meistens steht da alles relevante drin), wenn du sie nicht verstehst solltest du sie mitposten.

3) Was ist für dich ein "Frontend"? Ein Programm, in dem der User queries an die db schickt und die Ergebnisse präsentiert bekommt? Oder eine (statische) Sicht auf die Daten, die Queries sind vordefiniert (und vorm User versteckt), ebenso das komplette Tabellenlayout usw.

Wenn deine Klasse dieses eine bestimmte QSqlQuery-Objekt über die komplette Lebenszeit benötigt, kannst du es natürlich als Member speichern (gilt übrigens nicht nur für QSqlQuery). In den meisten Fällen ist das aber nicht notwendig, Queries werden dynamisch generiert und das Ergebnis gleich verarbeitet, das Query-Objekt wird danach nicht mehr benötigt. So wie ich sehe hast du auch ein QSqlQueryModel. Dieses speichert doch sowieso schon das Query ab (weil dieses Model das auch so braucht), dann brauchst du doch das Query nicht noch separat speichern.

Was für Funktionen wären das denn?
Ich sehe beim Design das Problem, dass du die Sicht auf eine Tabelle in einer eigenen Klasse kapseln willst. Eine Datenbank hat aber meist mehrere Tabellen, die untereinander verknüpft sind (Relationen).
Aber ohne genauerer Beschreibung des Problems + mehr Code (z.B. die vollständige Klassendefinition) kann man da eigentlich gar nix sagen :)
Bronski
Beiträge: 44
Registriert: 10. Oktober 2008 13:46

Beitrag von Bronski »

Vielen Dank :)
Das hat mir alles sehr geholfen.
Beim Konstruktor war ich einfach unsicher, und das die Daten im Model nicht verloren gehen war mir, da nocht nicht ganz klar.
Antworten