2017-05-02 3 views
0

Javaプログラミングでコーディングするとき、私は以下のような質問があります。効率的にJavaクラスの関数ポインタを作成するには?

以下はC++コードです。ご存知のように、のSomParam classは、関数ポインタです。ユーザがファンクションアドレスをコンストラクタのAlphaに設定すると、変数Alphaは現在の関数を実行します。

double lin_alpha(double alpha_0, int t, Subscript rlen, double) { 
    return alpha_0 * (1.0 - (double) t/rlen); 
} 

double inv_alpha(double alpha_0, int t, Subscript rlen, double C) { 
    //double C = rlen/INV_ALPHA_CONST; 

    return alpha_0 * C/(C + t); 
} 

#define LIN_ALPHA 1 
#define INV_ALPHA 2 

class SomParam{ 
public: 
    typedef double Alpha(double, int, int, double); 
protected: 
    Alpha *_alpha; 
    int _xdim; 
    int _ydim; 

public: 
    SomParam(int AlphaType,int xdim, int ydim) { 
     if (AlphaType == LIN_ALPHA) _alpha = lin_alpha; 
     else _alpha = lin_alpha; 
    _xdim = xdim; 
    _ydim = ydim; 
    } 

私の質問は、上記のコードをJavaバージョンに変換する方法を知りたいということです。 Javaにはポインタの概念がないので、Javaバージョンに変換するのは苦労しました。私はJavaで関数ポインタを置き換えることができるかもしれないことを知っていましたが、私のコードには適用できませんでした。 上記のものをjavaバージョンに変換するにはどうすればよいですか?

ps。私はJavaを使用しておりますので、あなたがラムダ式を使用してはならないことを願っています7.

+0

私はJavaに関数ポインタがあるとは思わない。しかし、java8のlambdaパラメータは、関数をパラメータとして渡すように見えます。 – Tiina

+0

Java 8を使ってみませんか?Java 7は現在かなり古くから使われていません。 –

答えて

1

これを行う最善の方法は、Java 8ラムダ式です。しかし、あなたがそれらを避けたいので、C++コードのJava 7への大まかな翻訳があります。

私は、静的な内部インターフェイスを使って関数ポインタのタイプと、このインターフェイスの匿名実装のインスタンスを表しています関数自体を表現する。私の意見では、これはenumを使用するよりも優れています。なぜなら、同じシグネチャを持っていること以外は、さまざまな機能間の関係を意味しないからです。

これをすべて定数で設定し、インスタンス化しているオブジェクトに格納するのに適切な定数値を選択する方法を示しました。私はデータ型などの自由をいくつか取ってきました。

public class AlphaAdjuster { 

    private static interface AlphaCalculator { 
     double calculate(double alpha0, int t, int rlen, double c); 
    } 

    public static final int LIN_ALPHA = 1; 
    public static final int INV_ALPHA = 2; 
    private static final AlphaCalculator LIN_ALPHA_CALCULATOR = new AlphaCalculator(){ 
     @Override 
     public double calculate(double alpha0, int t, int rlen, double c) { 
      return alpha0 * (1.0 - (double) t/rlen); 
     }}; 
    private static final AlphaCalculator INV_ALPHA_CALCULATOR = new AlphaCalculator(){ 
     @Override 
     public double calculate(double alpha0, int t, int rlen, double c) { 
      return alpha0 * c/(c + t); 
     }}; 

    private AlphaCalculator calculator; 
    private int xDim; 
    private int yDim; 

    public AlphaAdjuster(int alphaType, int xDim, int yDim) { 
     if (alphaType == LIN_ALPHA) { 
      calculator = LIN_ALPHA_CALCULATOR; 
     } else { 
      calculator = INV_ALPHA_CALCULATOR; 
     } 
     this.xDim = xDim; 
     this.yDim = yDim; 
    } 

    public double calculate(double alpha0, int t, int rlen, double c) { 
     return calculator.calculate(alpha0, t, rlen, c); 
    } 
} 
3

私は2つの機能とパッシングを実装戦略パターンの列挙型を作成することをお勧めしている直接あなたのコンストラクタへ:

public enum AlphaType { 
    LIN_ALPHA { 
     @Override 
     public double compute(double alpha_0, int t, Subscript rlen, double C) { 
      // FIXME t/rlen isn't valid in Java 
      return alpha_0 * (1.0 - (double) t/rlen); 
     } 
    }, 

    INV_ALPHA { 
     @Override 
     public double compute(double alpha_0, int t, Subscript rlen, double C) { 
      //double C = rlen/INV_ALPHA_CONST; 
      return alpha_0 * C/(C + t); 
     } 
    }; 

    public abstract double compute(double alpha_0, int t, Subscript rlen, double C); 
} 
-1

I C++にはあまりよく慣れていませんが、私はあなたが望むものを理解していると思います。

インターフェイスが適切であると思われます。インターフェイスhereについて読むことができますが、彼らはあなたが望むものを達成します。例えば

、あなたがインターフェイスを持っていると言う:

public interface MyInterface { 
    public int sort(int a, int b); 
} 

これはMyInterfaceのユーザーは、彼らが望むものに応じて、自分のsort()メソッドを定義することができます。

MyInterface foo = new MyInterface(){ 
    @Override 
    public int sort(int a, int b){ 
     return (a >= b)? a : b; 
    } 
} 

これは、最大番号によるソートを与えるMyInterfaceをインスタンス化します。 foo.sort(1,4)を呼び出すと、4が返されます。

あなたのケースでは、public double alpha(double a, int b, int b, double c)のような方法のインターフェイスがあります。次に、ユーザーは自分のインターフェースをインスタンス化し、alpha()メソッドをオーバーライドして、必要な処理を行います。

+0

私は決してインターフェイスを関数ポインタとして考えなかった。私のアドバイスは、確かな答えに固執し、C++とJavaの間の相関関係に依存しないことです。 – Makoto

+0

@Makoto合意したように、私はこの種の接続を行うべきではないと思っていますが、私はインターフェイスをC++で説明しようとしていたので、理解できました。インターフェイスが関数ポインタと異なることを明確にするために編集しますが、この例では、彼が望むものを達成するために使用できます。 – coolioasjulio

+0

この回答には良い解決策があります。残念ながら、最後の文の用語は非常に奇妙です。インタフェースをインスタンス化せずにメソッドをオーバーライドします。インターフェイスの匿名実装をインスタンス化します。 –

関連する問題