0

我正在开发一个可以使用共享库管理的应用程序。我创建了一个接口类,在这个类中有一些虚拟方法/成员。例如有一个名为 的方法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);当我编译管理器库时,编译器说“Log() 方法未实现!”

EDIT2: 这是我的代码,如果有人想在里面看的话。

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

4

1 回答 1

0

我认为更适合这个的是composition。与其尝试在基类 (ManagerBase) 中定义变量行为,不如让 Manager 定义行为应该发生的时间,并将该行为作为自己的对象传递给 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 中的引用,并公开设置器以便您可以设置任何您喜欢的行为定义对象。这使您可以做一些有趣的事情,例如,通过实现 ILogger 的 CFileLogger 和 CDatabaseLogger 版本并适当地设置它们,根据配置文件设置更改您记录的内容。

于 2013-08-19T17:16:51.293 回答