C++ 将类作为参数传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1474416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:07:14  来源:igfitidea点击:

C++ Passing a class as a parameter

c++

提问by Undawned

I'm wondering if it's possible to pass a class as a parameter in c++. Not passing a Class Object, but the class itself which would allow me to use this class like this.

我想知道是否可以在 C++ 中将类作为参数传递。不是传递类对象,而是传递类本身,它允许我像这样使用这个类。

void MyFunction(ClassParam mClass)
{
    mClass *tmp = new mClass();
}

The above is not real code, but it hopefully explains what I'm trying to do in an example.

以上不是真正的代码,但它希望在一个例子中解释我想要做的事情。

回答by Mehrdad Afshari

You can use templates to accomplish something similar (but not exactly that):

您可以使用模板来完成类似的事情(但不完全是这样):

template<class T>
void MyFunction()
{
    T *tmp = new T();
}

and call it with MyFunction<MyClassName>().

并用MyFunction<MyClassName>().

Note that this way, you can't use a "variable" in place of T. It should be known at compile time.

请注意,这样,您不能使用“变量”代替T. 它应该在编译时知道。

回答by Andy

C++ does not store meta data about classes as other languages do. Assuming that you always use a class with a parameterless constructor, you can use templates to achieve the same thing:

C++ 不像其他语言那样存储关于类的元数据。假设您始终使用带有无参数构造函数的类,您可以使用模板来实现相同的目的:

template <typename T>
void MyFunction()
{
    T* p = new T;
}

回答by Norman

You could also pass in a function pointer that when called creates an instance of whatever you want and returns that.

您还可以传入一个函数指针,该指针在调用时会创建您想要的任何实例并返回该实例。

void MyFunction(ClassCreatorPtr makeClassFn)
{
    void * myObject = makeClassFn();
}

You'd need to have it return a pointer to a base class to do anything really interesting with it.

你需要让它返回一个指向基类的指针才能用它做任何真正有趣的事情。

回答by Yannick Motton

You are looking for templates

您正在寻找模板

回答by Al Conrad

An alternative to templates is to use a lambda closure with C++11. Here's my preference.

模板的替代方法是在 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 &param1
    // 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 =
        [&param1, &param2](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 =
        [&paramX, &paramY](const IParams & interface_params)->IClass * {
            return new SomeCls2DerivedFromIClass(interface_params,
                paramX, paramY);
        };
    IClass * mCls = MyFunctionThatDoesStuff(interface_params,
        cls_allocator);
}

The above code idea works well for a quick builder pattern or some factory pattern variation. The lambda is basically a factory method. To make it even more dynamic you can use auto for parameter typing. Something like this.

上面的代码思想适用于快速构建器模式或一些工厂模式变体。lambda 基本上是一个工厂方法。为了使其更加动态,您可以使用 auto 进行参数输入。像这样的东西。

auto * MyFunctionThatDoesStuff(const auto & interface_params,
    std::function<auto * (const auto & interface_params)> cls_allocator);

I'm coming at this from Python influence where you can just pass the class type to the function.

我来自 Python 的影响,您可以将类类型传递给函数。

回答by rmeador

You can create a static factory method on your class(es) that simply returns a new instance of the class and then you can pass around pointers to that function similarly to what you want to do in your example. Return types are covariant, so if all your classes implement the same interface, you can have the function pointer return that interface. If they don't all have a common interface, you'll probably be left with returning void *. Either way, if you need to use the specific subclass, you'll have to dynamic_cast.

您可以在您的类上创建一个静态工厂方法,它只返回该类的一个新实例,然后您可以将指针传递给该函数,类似于您在示例中想要执行的操作。返回类型是协变的,因此如果所有类都实现相同的接口,则可以让函数指针返回该接口。如果它们没有一个通用的接口,你可能只剩下返回void *. 无论哪种方式,如果您需要使用特定的子类,您都必须使用dynamic_cast.