使用宏替换工厂模式样式 API 中的"create()"函数

Using a macro to replace "create()" functions in a factory pattern style API

本文关键字:中的 create 函数 API 样式 替换 工厂 模式      更新时间:2023-10-16

我正在编写一个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()函数的返回类型更改为类类型指针,这确实允许以下内容:#define CREATE(T, ...) (new T())->init(__VA_ARGS__)(?

(请注意,这与其说是实际问题,不如说是一个学术问题,因为我已经使用私有create()函数实现了该解决方案,该解决方案运行良好,似乎是"最干净"的解决方案。我只是想知道是否也可以使用宏的解决方案......

您可以混合使用模板和宏:

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

和宏(转发私人内容(

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