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).


Anmelden zum Antworten