C ++接口继承与Factory

时间:2017-03-30 20:47:04

标签: c++ oop inheritance interface

我正在使用一个具有特定功能接口的库,以及一些功能实现。该库还提供了一个Factory对象,用于实例化正确的功能实现。

我需要通过向对象添加新方法来扩展有问题的功能,我想通过创建一个继承自库接口并滚动我自己的实现的新接口来实现这一目的。

例如:

class IFromLibrary
{
  virtual void LibraryMethod(void) = 0;
}

class IMyInterface : public IFromLibrary
{
  virtual void MyMethod(void) = 0;
  int SomeValue;
}

class TMyImplementation : public IMyInterface
{
  void LibraryMethod(void) { ... }
  void MyMethod(void) { ... }
}

我面临的问题是创建了一个TMyImplementation实例。就像我说的那样,库将实现的构造函数隐藏为私有成员,并使用Factory静态方法构造对象。

示例:

static IFromLibrary * createFromLibrary(int whatever) { ... }

因为它是库的范例,我也试图通过在我的实现类中创建自己的create来实现它:

static IMyInterface * createMyImplementation(int whatever) { ... }

我遇到的问题是我希望我的新实例化对象可以使用库工厂提供的值构建:

static IMyInterface * createMyImplementation(int whatever)
{
  IMyInterface * newObject = createFromLibrary(whatever); // this doesn't compile, evidently.
  newObject->SomeValue = SomeOtherValue; // init the parts of the object that belong to my interface
}

我正在尝试避免使用适配器模式(即将IFromLibrary指针包装在我的TMyImplementation类中并转发从IFromLibrary继承的所有方法调用)。这确实有效,但从我的观点来看,我发现在架构上我很奇怪,我同时继承并包装了一个类。如果可能的话,我也想避免所有转发锅炉板代码。

这可以以任何方式完成吗?

编辑:

  • 添加了私有构造函数仅用于实现的事实(对于混淆,抱歉@NirFriedman)。
  • 指定我希望(如果可能)避免适配器模式的原因(感谢@immibis获取模式名称)。

2 个答案:

答案 0 :(得分:1)

您可以使用decorator pattern(我之前说的“适配器模式”错误 - they are quite similar though) - 将TMyImplementation对象委托给LibraryMethod IFromLibrary你从图书馆得到的对象:

class TMyImplementation : public IMyInterface
{
    IFromLibrary *base;
public:
    TMyImplementation(IFromLibrary *base) : base(base) {}
    ~TMyImplementation() {delete base;} // ideally you would use a unique_ptr instead

   void LibraryMethod() {base->LibraryMethod();}
   void MyMethod() {...}
};

然后要创建TMyImplementation,您可以使用new TMyImplementation(createFromLibrary(whatever))

(请注意,模式只是设计的起点,而不是严格遵循的规则!例如,根据您的设计,您可以在构造函数中移动createFromLibrary调用)

答案 1 :(得分:0)

如果你能找到“createFromLibrary”的实现并在你的“createMyImplementation”中使用它,那将是很好的,如果不可能的话:

static IMyInterface * createMyImplementation(int whatever)
{
    IFromLibrary* newLibraryObject = createFromLibrary(whatever);
    IMyInterface* newObject = (IMyInterface*)malloc(sizeof(IMyInterface));
    memcpy(newObject, newLibraryObject, sizeof(IFromLibrary));
    newObject->SomeValue = SomeOtherValue;
    return newObject;
}

如果库保留了对象的跟踪,则无法保证可以正常工作,这样就会失去与“newObject”的连接,从而导致未定义的行为。

如果您的库具有类似“ReleaseFromLibrary(IFromLibrary * pObj)”的内容,请在完成“newObject”或“newLibraryObject”或两者时尝试调用它!  (其中任何一个都可能导致未定义的行为)。

无论如何我不喜欢这种解决方案,但没想到更好的事情了!