Objekt einer Klasse in einer Klasse



  • Hallo allerseits,

    ich sitze momentan an einem kleinen Projekt und habe dafür folgendes Szenario:
    Ich möchte mithilfe einer Klasse ein Verzeichnis auslesen und dann mittels einer Datenbank-Klasse Daten in eine Datenbank schreiben. Zunächst soll erstmal der Dateiname in die Datenbank.

    Nachfolgend erstmal die entsprechenden Code-Schnipsel^^
    database.h

    #include <mysql/mysql.h>
    
    #ifndef DATABASE_H
    #define	DATABASE_H
    
    class database {
    public:
        database(const char* _server, const char* _user, const char* _password, const char* _database, const char* _prefix);
        database(const database& orig);
        virtual ~database();
        MYSQL_RES query(const char* _query);
        MYSQL_ROW fetch();
        MYSQL_ROW fetch(MYSQL_RES *result);
    private:
        MYSQL *connection;
        MYSQL_RES *result;
    };
    
    #endif	/* DATABASE_H */
    

    directoryScanner.h

    #include "database.h";
    
    #ifndef DIRECTORYSCANNER_H
    #define	DIRECTORYSCANNER_H
    
    class directoryScanner {
    public:
        directoryScanner(const char* _parentDir);
        directoryScanner(const directoryScanner& orig);
        virtual ~directoryScanner();
    private:
        const char* parentDir;
        database db;
    };
    
    #endif	/* DIRECTORYSCANNER_H */
    

    database.cpp

    #include "directoryScanner.h"
    #include "database.h";
    
    directoryScanner::directoryScanner(const char* _parentDir) {
        this->parentDir = _parentDir;
        database *db = new database("localhost", "user", "pw", "db", "");
    }
    
    directoryScanner::directoryScanner(const directoryScanner& orig) {
    }
    
    directoryScanner::~directoryScanner() {
    }
    

    Beim Kompilieren bekomme ich nun folgenden Fehler:

    directoryScanner.cpp:11:58: error: no matching function for call to ‘database::database()’
    

    Habe ich da einen ganz falschen Ansatz vielleicht?
    Ich weiß halt das ich das in PHP immer so gemacht habe, also in einer Klasse eine andere Klasse als "Variable" definiert und diese dann im Konstruktor entsprechend intialisiert.
    Klar darf man von PHP nicht einfach so auf andere Sprache schließen^^ Aber ich dachte das dieser Ansatz prinzipiell funktionieren sollte..

    Gruß



  • Du hast eine Membervariable db, die kein Zeiger ist und eine lokale im Konstruktor, die ein Zeiger ist. Die Membervariable brauch einen Defaultkonstruktor, die lokale ist sehr schnell nicht mehr vorhanden.



  • Also wenn ich das richtig verstanden habe muss ich den Zeiger auf db im directoryScanner-Konstruktor entfernen?
    Und ein Default-Konstruktor wäre bei der Datenbank-Klasse ja eher weniger optimal, da ich ja auch irgendwie zur Datenbank selbst verbinden muss, daher hat die Datenbank nur den einen Konstruktor.



  • phost schrieb:

    Also wenn ich das richtig verstanden habe muss ich den Zeiger auf db im directoryScanner-Konstruktor entfernen?

    Ja

    Und ein Default-Konstruktor wäre bei der Datenbank-Klasse ja eher weniger optimal, da ich ja auch irgendwie zur Datenbank selbst verbinden muss, daher hat die Datenbank nur den einen Konstruktor.

    Ja, kann man so sehen. Und weiter?

    Ich kann PHP und klöppel mal eben ein C++ Programm zusammen ist kein guter Ansatz ...



  • Naja da ich mit dem Ansatz ja ganz offensichtlich nicht sehr weit kam bin ich ja nun hier 😉
    Learning by doing und so..

    Ich habe es jetzt aber zumindest scheinbar hinbekommen..
    Habe in meiner .h das so umgeändert:

    database *db(const char*, const char*, const char*, const char*, const char*);
    

    und mit den anderen Änderungen (Pointer) klappt es jetzt scheinbar wie es soll.



  • Die Betonung liegt vermutlich auf scheinbar!



  • Jupp genau da liegt sie 😉

    Aber solange ich keine anderen Tipps bekomme wie das besser zu lösen ist wird das wohl auch so bleiben.



  • Hallo phost,

    Stichwort: Initialisierungsliste

    directoryScanner::directoryScanner(const char* _parentDir)
      : parentDir(_parentDir),
        db("localhost", "user", "pw", "db", "")
    {
    }
    


  • Die Frage ist doch überhaupt mal, ob der DirectoryScanner überhaupt das Datenbankobjekt besitzen sollte. Wenn es wirklich nur um das Auslesen eines Verzeichnisses und deren Unterverzeichnisse geht kann man das über freie Funktionen machen.

    Pseudo code:

    void recurse_store_directories( const std::string& Directory, database& db )
    {
        foreach( const std::string& EntryName in Directory )
        {
           if( is_directory( EntryName ) ) recurse_store_directories( EntryName, db );
           else                            db.store_directory( EntryName );
        }
    }
    
    int main()
    {
       database db( ... );
    
       recurse_store_directories( "c:/tmp", db );
    }
    


  • Th69 schrieb:

    Hallo phost,

    Stichwort: Initialisierungsliste

    directoryScanner::directoryScanner(const char* _parentDir)
      : parentDir(_parentDir),
        db("localhost", "user", "pw", "db", "")
    {
    }
    

    Perfekt genau das habe ich gesucht, vielen dank!

    /edit: also den normalen Konstruktor konnte ich jetzt entsprechend umschreiben, allerdings weiß ich jetzt nicht wie ich den Copy-Konstruktor entsprechend anpassen muss..?
    ich habe dazu folgenden Thread gefunden http://www.mikrocontroller.net/topic/334014, allerdings verstehe ich den grad nicht wirklich 😕
    Bin allerdings auch etwas müde gerade, daher schaue ich mir den spätestens morgen nochmal "frisch" an, falls sich bis dahin keiner erbarmt hat *g*

    /edit2: okay die Lösung war deutlich einfacher als gedacht.. wenn ich die database-Klasse einfach genauso initalisiere wie im normalen Konstruktor läufts 👍


Anmelden zum Antworten