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

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

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

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

还有几个class不应从库外实例化,所以它们不提供publiccreate().

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

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

始终实例化一个内部 class。相反,如果有一个单一的(模板)函数或宏可以创建 any 内部 class 只需要一行代码,例如

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

上述函数(在全局共享 header 中定义为独立函数,因此是 inline 关键字)的问题是它绕过了 friend 声明在 classes 之间,因此无法编译。

另一方面,宏的问题是它不能"return"一个指向实例的指针,只要宏中有语句ret->init(),所以使用宏不可能像下面这样:

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

最后,我的问题是:

是否有可能创建一个可以按上述方式调用的宏(并且无需将所有 init() 函数的 return 类型更改为 class 类型指针,这确实允许以下内容:#define CREATE(T, ...) (new T())->init(__VA_ARGS__))?

(请注意,这是一个 学术 而不是 实用 问题,因为我已经使用私有 create() 函数,它工作得很好,似乎是 "cleanest" 解决方案。我只是想知道是否 也可能是 宏的解决方案...... )

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

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__)