使用宏替换工厂模式样式API

时间:2017-08-09 18:48:30

标签: c++ api-design

我正在编写一个C ++库,其中所有类都使用工厂模式,即具有私有空构造函数和私有void init()函数,它执行实际的初始化实例。可以由库用户实例化的类具有公共静态create()功能,该功能执行以下操作:

static Class* create(int arg1, int arg2) {
    Class* ret = new Class();
    ret->init(arg1, arg2);
    return ret;
}

还有几个类不能从库外部实例化,因此它们不提供公共create()

这些“内部类”之间确实存在一些friend关系,因此它们可以相互实例化。我们假设我想编写尽可能少的代码,所以我想避免为所有内部类声明和定义私有create()函数,但我也想避免编写

InternalClass* foo = new InternalClass(); 
foo->init();

内部类一直被实例化。相反,有一个(模板)函数或宏可以用一行代码创建任何内部类,这样会很好,例如。

template<class T, typename ...Args> inline T* create(Args... args) {
    T* ret = new T();
    ret->init(args...);
    return ret;
}

上述函数的问题(在全局共享头中定义为独立函数,即inline关键字)是它绕过类之间的friend声明,因此不会编译。

另一方面,宏的问题在于,只要宏内部有语句ret->init(),它就不能“返回”指向实例的指针,因此使用宏如下所示不可能:

InternalClass* foo = CREATE(InternalClass, arg1, arg2);

最后,我的问题是:

是否有可能创建一个可以以上述方式调用的宏(并且不将所有init()函数的返回类型更改为类类型指针,这确实允许以下内容:{{ 1}})?

(请注意,这是学术而不是实际问题,因为我已经使用私有#define CREATE(T, ...) (new T())->init(__VA_ARGS__)函数实现了解决方案完全没问题,似乎是“最干净”的解决方案。我只是想知道是否已经一个带有宏的解决方案......)

1 个答案:

答案 0 :(得分:1)

您可以混合模板和宏:

template <typename T, typename InitF, typename... Args>
T* CreateImpl(T* t, InitF init, Args&&...args)
{
    (t->*init)(std::forward<Args>(args)...);
    return t;
}

和MACRO(转发私人资料)

// I assume no overloads of T::init
#define CREATE(T, ...) CreateImpl(new T(), &T::init, __VA_ARGS__)