2016-08-04 7 views
0

Ich habe ein Problem, Instanz der Kindklasse in Elternklasse zu erstellen.C++ Singleton Kind in Elternklasse erstellen

Hier Definition von Singleton (Elternklasse)

db.hpp 
------- 
#ifndef DB_HPP 
#define DB_HPP 

#include <string> 
#include "mysqldb.hpp" 

class Db 
{ 
    public: 
    static Db& instance() 
    { 
     // can be added other database implementations 
     #ifdef DBMYSQL 
     static Db *instance = new MySQLDb(); 
     #elseif DBORACLE 
     //static Db *instance = new OracleDb(); 
     #endif 
     return *instance; 
    } 

    virtual ~Db() {} 
    virtual void Insert(std::string& query) = 0; 
    protected: 
    Db() {} 
}; 
#endif // DB_HPP 

und hier ist das Kind

mysqldb.hpp 
----------- 
#ifndef MYSQLDB_HPP 
#define MYSQLDB_HPP 

#include "db.hpp" 
#include <mysql.h> 

class MySQLDb : public Db 
{ 
    public: 
    virtual void Insert(std::string& query); 

    private: 
    MYSQL *MySQLConnection_; 
    MySQLDb(); 
    ~MySQLDb(); 
}; 
#endif // MYSQLDB_HPP 

Ich habe Fehler erwarteten Typ-Spezifizierer vor 'MySQLdb'

g++ -DDBMYSQL `mysql_config --cflags` `mysql_config --libs` -DBOOST_LOG_DYN_LINK -std=c++11 -c -o mysqldb.o mysqldb.cpp 

In file included from mysqldb.hpp:4:0, 
      from mysqldb.cpp:1: 
db.hpp: In static member function ‘static Db& Db::instance()’: 
db.hpp:16:35: error: expected type-specifier before ‘MySQLDb’ 
    static Db *instance = new MySQLDb(); 
          ^
Makefile:39: recipe for target 'mysqldb.o' failed 

Hast du eine Ahnung, was los ist?

+0

Sie haben eine zirkuläre Abhängigkeit mysqldb.hpp enthält db.hpp, die mysqldb.hpp enthält, die db.hp enthält .... keine andere Wahl als das Ändern Ihres Designs – Garf365

+0

Die Basisklasse muss über die untergeordnete Klasse wissen mach eins. Die untergeordnete Klasse muss die Basisklasse erstellen, wenn sie erstellt wird. Außer es ist ein Singleton, also kannst du nicht. SO muss das Kind auch ein Singleton sein. Und du machst nur einen von denen. Ich könnte das lösen. Aber ich möchte lieber nicht: Es gibt keinen (offensichtlichen) Grund dafür, dass die Basisklasse ein Singleton ist. Wenn Sie nur einen wollen, machen Sie einen. Im Allgemeinen können Sie kein Singleton als Basisklasse verwenden. – doctorlove

+0

Müssen Sie wirklich eine ganze Datei und nicht nur eine Deklaration in db.hpp einfügen? – YiFei

Antwort

1

Zunächst einmal haben Sie eine zirkuläre Abhängigkeit (das ist der Grund für die aktuellen Fehler Sie erhalten): Db auf MySQLDb abhängt, die auf Db hängt und so weiter für immer.

Dies ist sehr einfach zu lösen: Fügen Sie die "mysqldb.hpp" Header-Datei nach Sie die Db Klasse definiert. Verschieben Sie dann die Definition von Db::instance außerhalb der Klasse, aber denken Sie daran, sie explizit zu markieren inline. Von haben Sie eine Quelldatei, wo Sie die Db::instance Funktion implementieren, und nur weiterleiten Sie die MySQLDb Klasse in der "db.hpp2" Header-Datei, nicht die Datei "mysqldb.hpp".

Nachdem ich, dass Sie ein anderes Problem haben wird, nämlich, dass der MySQLDb Konstruktor ist privaten und die Db Klasse kann nicht darauf zugreifen. Dies kann gelöst werden, indem man Db eine friend von MySQLDb macht.


jedoch all dies, die zirkuläre Abhängigkeit und macht Db ein friend ist ein Zeichen für ein schlechtes Design, IMO.

Ich könnte stattdessen etwas wie Db eine reine abstrakte Klasse zu tun, und verschieben Sie die Factory-Funktion woanders. Vielleicht mit Vorlagen.

Singletons und Vererbung spielen selten gut zusammen.

Was ist, wenn Sie mehrere gleichzeitige Verbindungen haben möchten? Vielleicht zu verschiedenen Datenbanken unterschiedlicher Art? Kann das Singleton-Muster dann nicht verwenden.