使用共享库管理应用程序

时间:2013-08-19 12:40:17

标签: c++ pointers shared-libraries

我正在开发一个可以使用共享库管理的应用程序。我已经创建了一个接口类,在这个类中有一些虚拟方法/成员。例如,有一个名为Initialize()的方法,如果你想在开始时实现某些东西,你应该覆盖这个方法。

现在我想制作一个事件/回调系统来管理应用程序。怎么样?如果要将消息记录到控制台+日志文件,您将调用类似Log("Failed to initialize MySQL")的方法,但我不能使用接口。我尝试了类似的东西,但我失败了;

//ManagerBase Header
class ManagerBase
{
public:
    virtual void Initialize();
    void Log(char* message);
}
//Manager Library
class Manager : public ManagerBase
{
public:
    void Initialize() { Log((char*)"Manager's initialize!"); }
}

有人可以帮助我改进这项实施吗?

EDIT1:我在我的应用程序中实现了“Log()”功能。 (喜欢printf(“%s”,message); 当我编译Manager Library时,编译器说“Log()方法没有实现!”

EDIT2: Here is my codes,如果有人想看看它们。

EDIT3:我在尝试编译Manager库时收到此错误: 对`ManagerBase :: Log(char )的未定义引用[在Manager.cpp中] *

1 个答案:

答案 0 :(得分:0)

我认为更合适的是composition。您可以让Manager定义何时应该发生该行为,而不是尝试在基类(ManagerBase)中定义变量行为,并将该行为作为其自己的对象传递给Manager。不再需要ManagerBase。

// *** Behaviour interfaces ***
// ILogger.h
class ILogger
{
public:
  ~ILogger(){};

  virtual void Log( const char *pMessage ) = 0;
};

//*******************************

// IDatabse.h
class IDatabase
{
public:
  ~IDatabase(){}

  virtual void CreateDB( const char *pDBName ) = 0;
};

//*******************************
// ** Manager **
// Manager.h

class ILogger;
class IDatabase;

class CManager
{
public:
  CManager( 
    ILogger &logger,  
    IDatabase &db );  

  void Initialise( const char *pDBName );

private:
  ILogger &m_logger;
  IDatabase &m_db;
};

// Manager.cpp
#include "ILogger.h"
#include "IDatabase.h"

#include "Manager.h"

CManager::CManager( ILogger &logger, IDatabase &db )
  : m_logger(logger) // this is like registering a Log callback
  , m_db(db)         // and a (set of) db callback/s
{
}

void CManager::Initialise( const char *pDBName )
{ 
  m_logger.Log( "Initialising" ); // this is akin to raising a log 'event'

  m_db.CreateDB( pDBName ); // and a create DB event.
}

//*******************************
// ** Application **
// Application.h
#include "ILogger.h"
#include "IDatabase.h"
#include "Manager.h"

class CApp : public ILogger, public IDatabase
{
/* You don't have to have your main app inherit the interface. You could
   implement them as their own objects, owned by CApp, or at least
   something that is reachable when contructing CManager */
public:
  CApp()
  : m_Manager( *this, *this )
  {
    m_Manager.Initialise("MyAwesomeDatabaseOfDoom");
  } 

  // implement overrides for Log and CreateDB here.
  void Log( const char* pMessage ){}

  void CreateDB( const char *pDBName ){}

private:
  CManager m_Manager;
};

//*******************************
// ** Application **
// main.cpp

int main()
{ 
  CApp();
  return 0;
};

这只是一个快速模拟,所以如果它不编译就道歉。我希望它至少能说明这个想法。

如果您希望能够在运行时更改行为,则可以使用ILogger / IDatabase成员指针而不是CManager中的引用,并公开setter,以便您可以设置任何定义您喜欢的对象的行为。这使您可以执行有趣的操作,例如,根据配置文件设置更改您的日志,通过实现ILogger的CFileLogger和CDatabaseLogger版本并进行相应的设置。