简体   繁体   English

C ++将类作为参数传递

[英]C++ Passing a class as a parameter

I'm wondering if it's possible to pass a class as a parameter in c++. 我想知道是否可以在c ++中将类作为参数传递。 Not passing a Class Object, but the class itself which would allow me to use this class like this. 没有传递一个类对象,但类本身允许我像这样使用这个类。

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. 以上不是真正的代码,但它有希望解释我在一个例子中想要做的事情。

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 . 请注意,这样,您不能使用“变量”代替T It should be known at compile time. 它应该在编译时知道。

C++ does not store meta data about classes as other languages do. C ++不像其他语言那样存储关于类的元数据。 Assuming that you always use a class with a parameterless constructor, you can use templates to achieve the same thing: 假设您总是使用带无参数构造函数的类,您可以使用模板来实现相同的功能:

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

您正在寻找模板

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. 你需要让它返回一个指向基类的指针来做任何真正有趣的事情。

An alternative to templates is to use a lambda closure with C++11. 模板的替代方法是使用带有C ++ 11的lambda闭包。 Here's my preference. 这是我的偏好。

// 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. lambda基本上是一种工厂方法。 To make it even more dynamic you can use auto for parameter typing. 为了使其更加动态,您可以使用auto进行参数输入。 Something like this. 像这样的东西。

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影响力来到这里的,你可以将类类型传递给函数。

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 * . 如果它们都没有共同的接口,那么你可能会留下返回void * Either way, if you need to use the specific subclass, you'll have to dynamic_cast . 无论哪种方式,如果您需要使用特定的子类,您必须使用dynamic_cast

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM