使用宏替换工厂模式样式 "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__)
我正在编写一个 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__)