我正在编写一个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__)
函数实现了解决方案完全没问题,似乎是“最干净”的解决方案。我只是想知道是否已经一个带有宏的解决方案......)
答案 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__)