寻找一个更好的C ++类工厂 [英] Looking for a better C++ class factory

查看:114
本文介绍了寻找一个更好的C ++类工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序有几个对象(约50,到目前为止,但增长)。在应用程序中只有这些对象中的每个对象的一个​​实例,这些实例在组件之间共享。

I have an application that has several objects (about 50 so far, but growing). There is only one instance of each of these objects in the app and these instances get shared among components.

我所做的是从基础派生所有对象BrokeredObject类:

What I've done is derive all of the objects from a base BrokeredObject class:

class BrokeredObject
{
  virtual int GetInterfaceId() = 0;
};

每个对象类型都返回一个唯一的ID。这些ID保存在头文件中。

And each object type returns a unique ID. These IDs are maintained in a header file.

然后我有一个ObjectBroker工厂。当有人需要一个对象时,然后调用GetObjectByID()。 boker在STL列表中查看该对象是否已存在,如果存在,则返回它。如果没有,它创建它,将它放在列表中并返回它。一切都很好。

I then have an ObjectBroker "factory". When someone needs an object, then call GetObjectByID(). The boker looks in an STL list to see if the object already exists, if it does, it returns it. If not, it creates it, puts it in the list and returns it. All well and good.

BrokeredObject *GetObjectByID(int id)
{
  BrokeredObject *pObject;
  ObjectMap::iterator = m_objectList.find(id);
  // etc.
  if(found) return pObject;

  // not found, so create
  switch(id)
  {
    case 0: pObject = new TypeA; break;
    case 1: pObject = new TypeB; break;
    // etc.
    // I loathe this list
  }
  // add it to the list
  return pObject;
}

我觉得痛苦的是维护这个ID列表,实现它。我至少让我的消费者的生活稍微容易一些每个类型保存自己的ID的信息,如下:

What I find painful is maintaining this list of IDs and having to have each class implement it. I have at least made my consumer's lives slightly easier by having each type hold info about it's own ID like this:

class TypeA : public BrokeredObject
{
  static int get_InterfaceID() { return IID_TYPEA; }
  int GetInterfaceID() { return get_InterfaceID(); }
};

所以我可以得到这样的对象:

So I can get an object like this:

GetObjectByID(TypeA::get_InterfaceID());

不得不实际知道ID映射是什么,但我仍然不喜欢维护和潜在的错误。看来,如果我知道类型,为什么我还必须知道ID?

Intead of having to actually know what the ID mapping is but I still am not thrilled with the maintenance and the potential for errors. It seems that if I know the type, why should I also have to know the ID?

我想要的就是这样在C#:

What I long for is something like this in C#:

BrokeredObject GetOrCreateObject<T>() where T : BrokeredObject
{
  return new T();
}

ObjectBroker将基于类型创建对象传入。

Where the ObjectBroker would create the object based on the type passed in.

有C#破坏了我,这只是一个事实,C ++不能这样做,或有一种方法来实现这一点,我看不见?

Has C# spoiled me and it's just a fact of life that C++ can't do this or is there a way to achieve this that I'm not seeing?

推荐答案

我的用例往往会变得更复杂 - 我需要做一点对象初始化和我需要能够从不同的DLL加载对象基于配置(例如模拟对硬件的实际)。它开始看起来像COM和ATL是我去的地方,但我不想添加COM的重量到操作系统(这是在CE中完成)。

My use-case tended to get a little more complex - I needed the ability to do a little bit of object initialization and I needed to be able to load objects from different DLLs based on configuration (e.g. simulated versus actual for hardware). It started looking like COM and ATL was where I was headed, but I didn't want to add the weight of COM to the OS (this is being done in CE).

我最终使用的是基于模板(感谢 litb 让我走上轨道),看起来像这样:

What I ended up going with was template-based (thanks litb for putting me on track) and looks like this:

class INewTransModule
{
  public:
    virtual bool Init() { return true; }
    virtual bool Shutdown() { return true; }
};

template <typename T>
struct BrokeredObject
{
public:
    inline static T* GetInstance()
  {
    static T t;
    return &t;
  }
};

template <> 
struct BrokeredObject<INewTransModule>
{
public:
    inline static INewTransModule* GetInstance()
  {
    static INewTransModule t;
    // do stuff after creation
    ASSERT(t.Init());
    return &t;
  }
};

class OBJECTBROKER_API ObjectBroker
{
  public: 
    // these calls do configuration-based creations
    static ITraceTool  *GetTraceTool();
    static IEeprom     *GetEeprom();
    // etc
};

然后为了确保对象(因为它们是模板的) :

Then to ensure that the objects (since they're templated) actually get compiled I added definitions like these:

class EepromImpl: public BrokeredObject<EepromImpl>, public CEeprom
{
};

class SimEepromImpl: public BrokeredObject<SimEepromImpl>, public CSimEeprom
{
};

这篇关于寻找一个更好的C ++类工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆