首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用C++构建一个具有对象存储库的工厂?

用C++构建一个具有对象存储库的工厂?
EN

Stack Overflow用户
提问于 2009-11-26 11:20:11
回答 3查看 1.5K关注 0票数 1

我想要创建一个工厂,用于创建实现抽象接口的对象,这将返回对内部保存的对象的引用,并且对象不会被复制。这个想法与log4cxx/log4jLogger类设计中的基本相同。我还希望尽可能多地向客户端隐藏详细信息,即查看公开的.h文件不会显示私有成员等实现细节。例如:

代码语言:javascript
运行
复制
EncryptorRef = Encryptor::getEncryptor("AES");

我不知道是否有公认的已发布的准则/示例代码来进行这种设计,因为我不想重新发明轮子,而且这个任务是相当常见的。我想使用静态工厂方法、Singleton存储库以及对具体对象的智能指针/引用作为返回类型。问题:

  • 有这样的设计示例简单代码吗?( log4cxx的代码太复杂,不能用作骨架)
  • 如何将存储库完全隐藏在客户端面前,假设他只看到您建议使用智能引用或指针作为返回类型的纯抽象Encryptor类?是否有用于智能参考的标准实现?
  • ,其他建议将不胜感激

非常感谢!

EN

回答 3

Stack Overflow用户

发布于 2009-11-26 11:36:31

只有当客户端不再需要对对象的引用(例如释放一些锁或其他资源,或者减少一些引用计数)时,才可以使用智能指针作为返回值。如果没有必要这样做,我建议返回一个简单的参考。这样,客户就知道他不必管理对象的生命周期或诸如此类的东西。智能引用的标准实现是Boost.SmartPtr。至于隐藏实现,只需将要公开的接口放到纯抽象基类中,让客户端通过工厂获取实例。然后,他所需要的就是带有抽象基类的头、带有工厂声明的头以及要链接到的二进制文件。

票数 3
EN

Stack Overflow用户

发布于 2009-11-26 11:22:37

为了隐藏实现细节,我建议使用pImpl成语。

票数 0
EN

Stack Overflow用户

发布于 2009-11-26 18:52:00

若要隐藏实现细节,加密类是纯虚拟的,没有数据。这使得主头文件保持简单,并且没有实现细节。如果您想使用继承进行代码重用,那么使用类似于BaseEncryptionImpl的中间类(这将在私有/实现头文件中)。

只有实现静态工厂方法getEncryptor的源文件必须包括加密实现。

这个工厂方法应该返回一个std::auto_ptr,而不是一个原始指针,这样才能保证异常安全。备受诟病的auto_ptr是为从函数返回指针而设计的。此外,它还将头的外部依赖降低到标准库,而不是boost。类的用户可以根据自己的需要使用boost::smart_prtboost::scoped_ptr,两者都有auto_ptr构造函数。

最初,我会尽可能地保持getEncryptor的简单性,可能会使用if else if等来决定您应该创建哪个。这比在单例中实现AbstractFactory注册中心要简单得多。大多数情况下,注册表只是在移动问题。如何初始化注册表?您可以使用每个EncryptionImpl类定义的静态对象,其构造函数注册和析构函数取消寄存器,但如果链接器决定不需要这些对象,因此不将它们包含在可执行文件或库中,则可能会导致问题。

Encryptor.h

代码语言:javascript
运行
复制
class Encryptor {
public:
  virtual void encrypt(const Data & in, Data * out) = 0;
  virtual ~Encryptor();

  static std::auto_ptr<Encryptor> getEncryptor(const char * name);
};

Encryptor.cpp

代码语言:javascript
运行
复制
#include "Encryptor.h"
#include "EncryptorA.h"
#include "EncryptorB.h"

std::auto_ptr<Encryptor> Encryptor::getEncryptor(const char * name)
{
  // EncryptorA::NAME is a std::string
  if (EncryptorA::NAME == name) {
    return std::auto_ptr<Encryptor>(new EncryptorA);
  }
  else if (EncryptorB::NAME == name) {
    return std::auto_ptr<Encryptor>(new EncryptorB);
  }
  else {
    throw EncryptionNotDefined;
  }
}

Client.cpp

代码语言:javascript
运行
复制
void foo()
{
  boost::scoped_ptr enc(Encryption::getEncryption("FOO"));

  Data in = ...;
  Data out = ...;

  enc->encrypt(in, &out);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1803107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档