传递要使用的功能参数的任意信息

Passing arbitrary information for a functional parameter to use

本文关键字:功能 参数 任意 信息      更新时间:2023-10-16

In C++:

有一个对象,我叫Foo。

Foo对提供的数据集执行统计操作。该过程的第一步涉及拟合功能,并且可以提供功能参数,以便用户可以指定正在使用的模型类型。

问题是我现在遇到一种情况,即函数参数需要访问 Foo 中不存在的数据,而是使用 Foo 的对象中的数据,我将称之为 Bar。

所以Bar打电话给Foo,让Foo对Bar的数据进行操作。Bar 有一个特定的函数,它想要用作函数参数,但这个函数需要特定于 Bar 的信息。

  • 我不想传递 Bar,因为如果我编写 Foo 代码以接收 Bar,那么每次我有一个需要将附加信息传递给 Foo 的新对象时,我都必须调整 Foo 类以接受该对象。
  • 我不想修改Foo中的功能参数输入,因为这样我还必须为每个新的用例修改功能参数输入。

考虑使用一个基类,我称之为StandardFunc。然后,通过虚拟方法,Bar可以创建一个名为ModifiedFunc的对象,该对象派生自StandardFunc。它可以覆盖 StandardFunc 的函数,也可以提供附加信息作为类参数。这也不起作用,因为为了避免切片,我必须将 ModifiedFunc 类型转换为 StandardFunc。这意味着在 Foo 中,我必须更改每个新对象名称的类型转换行。

有人可以指出我正确的方向,如何允许用户将函数参数与函数所需的任意参数一起传递,而无需为每个不同的用例重新编码 Foo 类?我真的被困在这件事上。

编辑:伪代码示例:

class Foo
{
    void processHandler(function)
    void process();
    void process(function);
    void theUsualFunction(vector); //the default function used by process
    vector vec;
};
void Foo::process()
{
    processHandler(theUsualFunction);
}
void Foo::process(function f)
{
    processHandler(f)
}
void Foo::processHandler(function f)
{
    f(vec)
    //do other stuff to vec
}
void Foo::theUsualFunction(vector v)
{
    //default vec processor
}
class Bar
{
    int x;
    int y;
    vector vec;
    void theModifiedFunction(vector);
    void callFooToProcess();
};
void Bar::theModifiedFunction(vector v)
{
    //process v, but in a way that requires x and y
}
void Bar::callFooToProcess()
{
    Foo foo;
    foo.setVector(vec);
    process(theModifiedFunction); 
}

所以这段代码是我想要实现的一个例子,但它不能按照编写的方式工作。原因是因为我无法在不修改 Foo::p rocessHandler 的参数的情况下将 Bar::x 和 Bar::y 添加到函数 Foo::p rocessHandler(function) 中,而且我不想这样做,因为那样每个像 Bar 这样的新类和每个需要不同数据的新 theModifiedFunction 都需要我重写 processHandler 的参数。

这也不起作用,因为为了避免切片,我必须将 ModifiedFunc 类型转换为 StandardFunc。

仅当按值传递参数时,才会进行切片。你应该把它作为一个指针传递,这就是多态性应该如何工作。

此外,如果您将类设置为模板,则可以继续按值传递参数:

template<class Func>
class Foo {
    void doStuff(Func func) {
        ...
    }
}

但请记住,在这种情况下,Func必须在编译时知道。

虽然可能还有其他方法可以处理这种情况,但我建议考虑让 Bar 包含 Foo。这称为has-a关系[wiki]。这样做的好处是,您可以按原样使用 Foo,而无需修改 Foo 中的任何内容,并且 Bar 不需要传递其私有数据。希望以下代码片段能帮助您理解该概念。

public class Bar
{
    private Foo myFoo;
    private int myInfo;
    void a()
    {
        myFoo.doStuff(myInfo);
    }
}