1

我有以下设计问题,并且正在寻找最优雅、甚至更重要的最有效的解决方案,因为这个问题来自性能是一个问题的环境。简单地说,我有一个类“Function_processor”,它对实函数进行一些计算(例如计算实函数的根),我还有另一个类“A”,它具有不同的此类函数,需要使用 Function_processor 对它们执行计算.

Function_processor 应该尽可能通用(例如,不为各种不同的对象提供接口),而只是坚持自己的任务(对任何函数进行计算)。

#include "function_processor.h"

class A {
    double a;
public:
    A(double a) : a(a) {}
    double function1(double x) {
        return a*x;
    }
    double function2(double x){
        return a*x*x;
    }

    double calculate_sth() {
        Function_processor function_processor(3*a+1, 7);
        return function_processor.do_sth(&function1);
    }
};

class Function_processor {
    double p1, p2;

public:
    Function_processor(double parameter1, double parameter2);

    double do_sth(double (*function)(double));
    double do_sth_else(double (*function)(double));
};

显然我不能像下面的例子那样传递成员函数 A::function1/2 (我知道,但这大致是我认为可读的代码)。我也不能使 function1/2 成为静态的,因为它们使用了非静态成员 a。我确信我可以使用诸如 std::bind 或模板之类的东西(尽管我对这些东西几乎没有任何经验),但我最关心的是我会得到的性能。

什么是我的问题的最佳(良好的代码和快速的性能)解决方案?

谢谢你的帮助 !

4

2 回答 2

1

无论是从纯 OO 的角度来看,还是从功能或程序 POV 的角度来看,这都不是最好的方法。首先,您的 A 类实际上只不过是一个必须实例化的命名空间。就个人而言,我只是把它的函数作为自由浮动的 C 风格的函数——也许在某个名称空间中,这样你就可以得到某种分类。

以下是您在纯 OO 中的操作方式:

class Function
{
    virtual double Execute(double value);
};
class Function1 : public Function
{
    virtual double Execute(double value) { ... }
};

class FunctionProcessor
{
    void Process(Function & f)
    {
         ...
    }
}

这样,您可以实例化Function1 对象Function1并将FunctionProcessor其发送到 Process 方法。您可以从中派生任何内容Function并将其传递给 Process。

一种类似但更通用的方法是使用模板:

template <class T>
class FunctionProcessor
{
    void Process()
    {
        T & function;
        ...
    }
}

您可以将任何东西作为 T 传递,但在这种情况下,T 成为编译时依赖项,因此您必须在代码中传递它。这里不允许有动态的东西!

这是另一种模板化机制,这次使用简单的函数而不是类:

template <class T>
void Process(T & function)
{
    ...
    double v1 = function(x1);
    double v2 = function(x2);
    ...
}

你可以这样称呼这个东西:

double function1(double val)
{
    return blah;
}

struct function2
{
    double operator()(double val) { return blah; }
};

// somewhere else
FunctionProcessor(function1);
FunctionProcessor(function2());

您可以将此方法用于任何可以使用正确签名调用的内容;简单的函数、类中的静态方法、函子(struct function2如上)、std::mem_fun对象、新奇的 c++11 lambdas、...如果您使用函子,您可以在构造函数中向它们传递参数,就像任何对象一样。

最后一个可能是我会做的;如果您在编译时知道要调用什么,这是最快的,并且在阅读客户端代码时是最简单的。如果由于某种原因它必须非常松散耦合,我会采用第一个基于类的方法。我个人认为这种情况很少见,尤其是当您描述问题时。

如果你仍然想使用你的class A,如果它们不需要成员访问,则将所有函数设为静态。否则,看std::mem_fun。我仍然不鼓励这种方法。

于 2013-10-14T18:59:02.833 回答
0

如果我理解正确,您正在搜索的似乎是指向成员函数的指针:

double do_sth(double (A::*function)(double));

但是,对于调用,您还需要一个 class 对象A。您也可以将其传递到function_processor构造函数中。

不过,不确定它的性能。

于 2013-10-14T18:42:12.527 回答