Initialisierung von Klassen
-
Hallo,
ich schreibe gerade eine Klasse für die Firebird-Datenbank, die von den Funktionsnamen und RETURN-Werten an eine ältere Klasse angepasst werden sollen(Im Prinzip sollen Funktionsnamen gleichen Namen, gleichen RETURN-Wert und gleiche Verwendung wie im bvereits bestehenden Projekt haben).
Meine Klassen nach Reihenfolge:
class CFDBConnection;
class CFDBStmt;
class CFDBRecord;Ich erstelle eine Instanz meiner Klasse Connection. In dieser Klasse weilt jedoch eine MEmberfunktion die eine andere Klasseninstanze als Übergabeparameter benötigt.
Heisst also: Ich möchte die CFDBStmt-Instanz an eine Instanz der Connection-Klasse übergeben, da aber die Connection-Klasse zuerst da ist, ist die Klasse CFDBStmt dort noch nicht bekannt.
Beispiel:
Class CFDBConnection { Funktion1(CFDBStmt* stm(noch nicht bekannt da unten erst definiert) *c,int test); } Class CFDBStmt { CFDBConnection con; // Ist bekannt, da vorher definiert. Funktion(int c,int d); }
Kann ich den Compiler austricksen? Wenn nicht, müsste ich eine Änderung reinbringen und könnte mich nicht mehr genau an die alte SQL-Klasse halten.
Vielen Dank!!
-
class CFDBStmt;
Stichwort Vorwärtsdeklaration
Warum hast du class mit einem großen C geschrieben?
edit: also die deklaration einfach vor beide Klassen schreiben
-
Das Zauberwort heißt "forward-Dekalration" - und da du nur Pointer verwenden willst, ist das sogar anwendbar (siehe Pellaon).
-
wie wärs wenn du vorher einen prototypen deklarierst:
class CFDBStmt; //Prototypendeklaration, jetzt ist diese Klasse auch der FDBConnection bekannt class CFDBConnection { Funktion1(CFDBStmt* stm(noch nicht bekannt da unten erst definiert) *c,int test); } class CFDBStmt { CFDBConnection con; // Ist bekannt, da vorher definiert. Funktion(int c,int d); }
-
hmmm....habe ich gemacht, trotzdem kommt folgende Meldung:
e:\Projekte\FDBDatabase\FDBConnection.cpp(126): error C2027: use of undefined type 'CFDBStmt'und zwar hier in der Funktion GetColumns:
// Anzahl der Spalten einer Tabelle int CFDBConnection::GetColumns(CFDBStmt *s, LPCTSTR table) { int AllColumns; CString SQLQueryGetColumns; SQLQueryGetColumns.Format("SELECT * FROM %s",(CString)table); s->tr->Start(); s->m_hStmt->Prepare((std::string)SQLQueryGetColumns); return s->m_hStmt->Columns(); }
Dateien:
//Die Headerdatei FDBConnection.h sieht so aus: class CFDBStmt; class CFDBConnection : public CWinThread { DECLARE_DYNCREATE(CFDBConnection) protected: CFDBConnection(); // protected constructor used by dynamic creation virtual ~CFDBConnection(); public: virtual BOOL InitInstance(); virtual int ExitInstance(); protected: DECLARE_MESSAGE_MAP() public: // Verbindung zur Datenbank aufnehmen bool Connect(void); // Gibt den Fehlerstring der letzten Operation zurück CString GetError(void); // STOP TALKING...Datenbankverbindung beenden void Disconnect(void); // Eine neue Datenbank erzeugen bool CreateDB(void); // Anzahl der Spalten einer Tabelle int GetColumns(CFDBStmt* s, LPCTSTR table); // Spaltengrösse der Spalte void GetColumnSize(void); // Anzahl der Spalten in der Tabelle der aktuellen Query muss vor Commit gespeichert werden. Und zwar hier!! int Columns; // IBPP-Datenbank Database db; // SQL-Dialect für die Instanz möglich: 1 bis 3, Unterschiede bitte der Firebird-Doku entnehmen int dialect; // Datenbank-Dateiname CString m_DbName; // Enthält die Fehlermeldung der letzten Operation ;-) wird bei jeder Exception in Connection.Klasse geschrieben CString m_ErrorStr; // Passwort(Standard:masterkey) CString m_Password; // Name des Servers(Standard:localhost) CString m_ServerName; // Benutzername(Standard:SYSDBA) CString m_UserName; }; //Und jetzt die Implementierung FDBConnection.cpp: // FDBConnection.cpp : implementation file // #include "stdafx.h" #include "FDBConnection.h" // CFDBConnection IMPLEMENT_DYNCREATE(CFDBConnection, CWinThread) CFDBConnection::CFDBConnection() : Columns(0) , dialect(0) , m_DbName(_T("")) , m_ErrorStr(_T("")) , m_Password(_T("")) , m_ServerName(_T("")) , m_UserName(_T("")) { } CFDBConnection::~CFDBConnection() { } BOOL CFDBConnection::InitInstance() { // TODO: perform and per-thread initialization here return TRUE; } int CFDBConnection::ExitInstance() { // TODO: perform any per-thread cleanup here return CWinThread::ExitInstance(); } BEGIN_MESSAGE_MAP(CFDBConnection, CWinThread) END_MESSAGE_MAP() // Verbindung zur Datenbank aufnehmen bool CFDBConnection::Connect(void) { // Ich weiss das ich quasi das Rad neu erfinde... try { db = DatabaseFactory((std::string)m_ServerName,(std::string)m_DbName,(std::string)m_UserName,(std::string)m_Password); db->Connect(); if(db->Connected()) { return true; } } catch(Exception &e) { m_ErrorStr.Format("%s",e.ErrorMessage()); return false; } catch(...) { m_ErrorStr.Format("Allgemeiner Fehler in CFDBConnection::Connect()"); return false; } } // Gibt den Fehlerstring der letzten Operation zurück CString CFDBConnection::GetError(void) { return m_ErrorStr; } // STOP TALKING...Datenbankverbindung beenden void CFDBConnection::Disconnect(void) { try { db->Disconnect(); // Jaja, ich weiss ..... ich schmunzel selber } catch(Exception &e) { m_ErrorStr.Format("%s",e.ErrorMessage()); } catch(...) { m_ErrorStr.Format("Allgemeiner Fehler in CFDBConnection::Disconnect()"); } } // Eine neue Datenbank erzeugen bool CFDBConnection::CreateDB(void) { try { db = DatabaseFactory((std::string)m_ServerName,(std::string)m_DbName,(std::string)m_UserName,(std::string)m_Password); db->Create(dialect); db->Connect(); if(db->Connected()) { return true; } } catch(Exception &e) { m_ErrorStr.Format("%s",*e.ErrorMessage()); return false; } catch(...) { m_ErrorStr.Format("Allgemeiner Fehler in CFDBConnection::CreateDB()"); return false; } } // Anzahl der Spalten einer Tabelle int CFDBConnection::GetColumns(CFDBStmt *s, LPCTSTR table) { int AllColumns; CString SQLQueryGetColumns; SQLQueryGetColumns.Format("SELECT * FROM %s",(CString)table); s->tr->Start(); s->m_hStmt->Prepare((std::string)SQLQueryGetColumns); return s->m_hStmt->Columns(); } // Spaltengrösse der Spalte void CFDBConnection::GetColumnSize(USHORT Column) { }
Für weiter Hilfe wäre ich sehr dankbar
-
in die cpp-Datei mal noch die Headerdatei zu CFDBStmt inkludieren(das Wort klingt schei*e *rofl*
)
-
Für die Deklaration der "CFDBConnection::GetColumns()" reicht die Forward-Deklaration vollkommen aus, für die Definition benötigst du dagegen alle Angaben über den Typ:
class CFDBStmt; class CFDBConnection { //Deklaration der Connection-Member } class CFDBStmt { //Deklaration der Stmt-Member } //ab hier die Definitionen:
Oder bei deiner Verteilung auf mehrere Header: setz' ein "#include "FDBStmt.h" an den Anfang der "FDBConnection.cpp" (hinter die vorhandenen Includes).