通过operator new定义简单对象工厂的正确语法

时间:2015-03-25 19:51:53

标签: c++ c++11 lambda factory

以下是我想要实现的基本概要

class Interface {
public:
  virtual ~Interface () {}
  virtual void work() = 0;
  static Interface *create();
  static void setFactory(std::function<Interface *()>);
}
在Interface.cpp中

我有

static std::function<Interface *()>  factory = nullptr;
Interface *Interface ::create() { return factory(); }
void Interface::setFactory(std::function<Interface *()> someFactory) {
   factory = someFactory;
}

另外我有

class Implementation : public Interface {
...
}

我确保打电话

Interface::setFactory([]() -> Interface * { return new Implementation(); });

在对Interface :: create()进行任何调用之前。我所看到的是静态工厂变量已设置(不再是nullptr),因此对setFactory的调用确实有效。但是,生成的工厂为空,并且对Interface :: create()的调用将崩溃。我可能通过使用operator()创建一个结构,但我想知道我的lambda表达式是否有错误。

值得一提的是,我使用的是MSVC2013

1 个答案:

答案 0 :(得分:1)

您可能遇到静态初始化订单问题。

我的理论是,在构建之前将factory分配给,然后构建(擦除其状态),然后调用create

MSVC2015支持魔术静态局部变量,这主要解决了这个问题。

namespace {
  std::function<Interface *()>& factory() {
    static std::function<Interface *()> retval;
    return retval;
  }
}

now factory()包装一个静态局部变量,该变量保证在第一次调用函数时或之前构造,并且只构造一次。

在MSVC2013中做同等事情更难。如果您知道在main开始调用它之前不会有多个线程,您可以执行上述操作:

static auto&& force_call = factory();

main开始之前强行拨打电话。