c ++ singleton在父类中创建子级

时间:2016-08-04 10:33:53

标签: c++ class singleton

我在父母一方创建子类的实例时遇到问题。

这是singleton(父类)的定义

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

这是孩子

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

我在'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

你知道什么是错的吗?

1 个答案:

答案 0 :(得分:1)

首先,你有一个循环依赖(这是你得到当前错误背后的原因):Db取决于MySQLDb,它取决于{{1}永远等等。

这很容易解决:在定义Db类之后包含"mysqldb.hpp"头文件。然后在类之外移动Db的定义,但请记住明确标记它Db::instance。有一个源文件,您实现inline函数,并且只转发声明Db::instance头文件中的MySQLDb类,不包括"db.hpp2"文件。

执行此操作后,您将遇到另一个问题,即"mysqldb.hpp"构造函数是私有,而MySQLDb类无法访问它。这可以通过Db Db friend来解决。

然而 所有这一切,循环依赖并使MySQLDb成为Db是IMO设计不良的标志。

我可能会做一些像friend这样的纯抽象类,并将工厂函数移到其他地方。也许使用模板。

单身人士和继承人很少一起玩。

此外,如果您想要多个同时连接怎么办?也许对不同类型的不同数据库?那时不能使用单例模式。