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

时间:2016-03-04 21:11:39

标签: c++ polymorphism

在C ++中:

我有一个对象,我会打电话给Foo。

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

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

因此Bar调用Foo让Foo对Bar的数据进行操作。 Bar具有要用作功能参数的特定功能,但此功能需要特定于Bar的信息。

  • 我不想通过Bar,因为如果我将Foo编码为接收Bar,那么每当我有一个新对象需要传递给Foo的其他信息时,我将不得不调整Foo类来接受对象。
  • 我不想修改Foo中的功能参数输入,因为我们也必须修改每个新用例的功能参数输入。

我考虑使用基类I调用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); 
}

所以这段代码就是我想要实现的一个例子,但它并没有按照书面形式工作。原因是因为我没有办法将Bar :: x和Bar :: y添加到函数Foo :: processHandler(function)而不修改Foo :: processHandler的参数,我不想这样做因为然后每个像Bar这样的新类和每个需要不同数据的新修改函数都需要我重写processHandler的参数。

2 个答案:

答案 0 :(得分:0)

  

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

仅在按值传递参数时才会发生切片。你应该将它作为指针传递,这就是多态性应该如何工作。

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

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

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

答案 1 :(得分:0)

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

public class Bar
{
    private Foo myFoo;
    private int myInfo;

    void a()
    {
        myFoo.doStuff(myInfo);
    }
}