我想知道是否有可能在C++中传递一个类作为参数。 不传递一个Class对象,而是允许我像这样使用这个类的类本身。C++传递一个类作为参数
void MyFunction(ClassParam mClass)
{
mClass *tmp = new mClass();
}
以上不是真实代码,但它有希望解释我在示例中要做的事情。
我想知道是否有可能在C++中传递一个类作为参数。 不传递一个Class对象,而是允许我像这样使用这个类的类本身。C++传递一个类作为参数
void MyFunction(ClassParam mClass)
{
mClass *tmp = new mClass();
}
以上不是真实代码,但它有希望解释我在示例中要做的事情。
您可以使用模板来完成类似的(但不完全是)的东西:
template<class T>
void MyFunction()
{
T *tmp = new T();
}
与MyFunction<MyClassName>()
调用它。
请注意,通过这种方式,您不能使用“变量”代替T
。它应该在编译时知道。
您正在寻找templates
C++不像其他语言那样存储有关类的元数据。假设你一直使用一类具有无参数的构造函数,你可以使用模板来实现同样的事情:
template <typename T>
void MyFunction()
{
T* p = new T;
}
您可以创建在您的类(ES)静态工厂方法,它只是返回的一个新实例类,然后你可以传递指向该函数的指针,类似于你想要在你的例子中做的。返回类型是协变的,所以如果你所有的类都实现了相同的接口,你可以让函数指针返回该接口。如果他们没有一个共同的界面,你可能会留下返回void *
。无论哪种方式,如果您需要使用特定的子类,则必须使用dynamic_cast
。
你也可以传入一个函数指针,当被调用时创建一个你想要的实例并返回它。
void MyFunction(ClassCreatorPtr makeClassFn)
{
void * myObject = makeClassFn();
}
你需要让它返回一个指向基类的指针来做任何有趣的事情。
模板的替代方法是使用C++ 11的lambda封闭。这是我的偏好。
// in header file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator);
// in source file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator) {
// Some processing. Perhaps the interface_params are generated
// inside this function instead of being passed to it.
IClass * mCls = cls_allocator(interface_params);
// Do whatever with mCls
return mCls;
}
// Somewhere else in the code.
{
Param1Type param1 = whatever1;
Param2Type param1 = whatever2;
// param1, param2, etc. are parameters that only
// SomeClsDerivedFromIClass constructor knows about. The syntax ¶m1
// achieves the closure.
// interface_param1 is common to all classes derived from IClass.
// Could more than one parameter. These parameters are parameters that
// vary from different calls of MyFunctionThatDoesStuff in different
// places.
auto cls_allocator =
[¶m1, ¶m2](const IParams & interface_params)->IClass * {
return new SomeCls1DerivedFromIClass(interface_params,
param1, param2);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
// Somewhere else in the code again.
{
ParamXType paramX = whateverX;
ParamYType paramY = whateverY;
auto cls_allocator =
[¶mX, ¶mY](const IParams & interface_params)->IClass * {
return new SomeCls2DerivedFromIClass(interface_params,
paramX, paramY);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
上面的代码思想对于快速生成器模式或某些工厂模式变化很有效。 lambda基本上是一种工厂方法。为了使它更加动态,您可以使用自动进行参数输入。像这样的东西。
auto * MyFunctionThatDoesStuff(const auto & interface_params,
std::function<auto * (const auto & interface_params)> cls_allocator);
我来自Python的影响力,你可以将类类型传递给函数。
2009-09-24 22:14:07
并非所有的语言都存储有关该程序的元数据。这是现代语言的一个相对较新的特征。 –@Martin,这是一个有趣的“相对较新”的定义,考虑到当时相当主流的Smalltalk,并且有相当多的代码写在里面,70年代就是这样做的:) – 2009-09-24 22:19:36
与许多归因于Smalltalk的东西,Lisp在20世纪50年代就在那里 - 整个程序是一个可以检查和操纵的数据结构。 – 2009-09-25 08:50:34