3

抽象基底クラスを書きたい

class func_double_double_t : public unary_function<double, double>
{
    virtual double operator()(double x) = 0;
};

いくつかの異なるタイプに特化する

class func_pow_t : public func_double_double_t
{
 public:
    func_pow_t(double exponent) : exponent_(exponent) {};
    virtual double operator()(double x) { return pow(x, exponent_); };
}

class func_exp_t : public func_double_double_t
...

必要に応じてこれらを関数に渡します。

double make_some_calculation(double num, func_double_double_t f)
{
     return f(x);
}

func_double_double_tしかし、抽象的であるため、型のオブジェクトを定義できません。関数にポインターを渡すことはできますが、flikeを使用f->operator()(num)することは、そもそも演算子のオーバーロードの精神に反するようです。((*f)(num)より良いですが、それでも。)

演算子のオーバーロードとそのような抽象化をうまく連携させる方法はありますか?

4

5 に答える 5

3

関数に参照を渡すだけです。

double make_some_calculation(double num, func_double_double_t& f)
{
    return f(x);
}
于 2012-07-05T20:19:03.043 に答える
1

関数を参照として渡すことでそこに到達できますが、C++11 標準には次のファンクター型が組み込まれています。

double make_some_calculation(double d, std::function< double(double) > f) {
   return f(d);
}


...
auto add_2=std::bind( std::plus(), 2.0 );
double result=make_some_calculation(1.1, add_2);
于 2012-07-05T20:22:30.620 に答える
0

明白な答えは参照を渡すことであるように思われるので、f(num)通常どおりに:を使用します。

実行時にさまざまな関数オブジェクトを使用できるようにする必要がない限り(たとえば、さまざまなタイプのファンクターの配列があり、それらをすべてループで呼び出す)、代わりに関数をテンプレートパラメーターで呼び出すことを検討してください。

template <class F>
double do_some_calculation(double num) { 
    return f(num);
}

コンパイル時に使用する関数がわかっている場合は、通常、これが優先されます。

于 2012-07-05T20:19:00.793 に答える
0

再検討したい基本概念がいくつかあります。まず、質問に対する直接的な答えは、参照を渡す必要があるということです。これにより、優れた構文とさまざまな派生インスタンスを渡すことができます。

それを超えて、ランタイムのポリモーフィックな動作が必要なoperator()場合は、基本クラスで仮想化する必要があります(質問へのコピー中に除外される可能性がありますか?-つまりvirtual純粋な指定子 =0がないと、形式が正しくありません)

于 2012-07-05T20:21:10.790 に答える
0

ランタイム ポリモーフィズムを使用して実装しようとしている場合は、次のものが必要です。

  1. 基本クラスの関数を宣言する必要がありますvirtual(どこにありますか?)

    class func_double_double_t : public unary_function<double, double>
    {
        virtual double operator()(double x) = 0;
    };
    
  2. 基底クラスから継承する場合、派生クラスは必要ありませんvirtual(なぜそこに置いたのですか?)

    class func_pow_t : public func_double_double_t {
      ...
    
  3. 呼び出し元の関数は、ポインターまたは参照によってオブジェクトを受け取る必要があります

    double make_some_calculation(double num, func_double_double_t& f)
    {
      return f(x);
    }
    

    また

    double make_some_calculation(double num, func_double_double_t* f)
    {
      return (*f)(x);
    }
    
于 2012-07-05T20:21:12.710 に答える