2

ExpressionObjective-Cクラスで使用したいメソッドを持つC++クラス' 'があります' GraphVC'。

class Expression {
    double evaluate(double);
}

そして私のObjective-Cクラス:

@implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
@end

C ++オブジェクトとは対照的に、doubleを取り、doubleを返す関数ポインターを渡すのが最も簡単だと思いましたが、を使用してあまり成功していませんfunctional.h。Objective-CのC++メソッドを使用する最良の方法は何ですか?

編集:あなたの迅速な応答をありがとう。少し詳しく説明させてください...C++で記述されたバックエンドがあり、Expression型のオブジェクトを操作します。有理数、多項式、単項式などのサブクラスがあります。私の最初のアイデアは、からmem_funを使用することでしたが、この方法でコードをコンパイルすることはできませんでした。また、bind1stを使用してthisポインターをバインドするのにも問題がありました。

  • Objective-Cラッパーを作成することも可能ですが、既存のevaluate()関数を使用したいので、バックエンドとiPhoneGUIクラスの明確な分離を破りたくありません。
  • グローバル式を使用したり、静的メソッドを使用したりすることはできません(任意のExpressionインスタンスをプロットする必要があります)。

C ++メンバー関数(静的関数や既存のC関数ではない)をObjective-Cオブジェクトに渡す必要があることをより明確に述べる必要があります。誰かがC++を<functional>使用して、メンバー関数をObjective-Cオブジェクトで使用できるポインターに変換することができましたか?それともObjective-Cラッパーを使用する必要がありますか?

4

5 に答える 5

2

C ++でメソッドへのポインターを作成する場合は、次のようにクラス名を含める必要があります。

class Foo
{
  public:
    double bar(double d)
    {
      return d;
    }
};

void call_using_obj_and_method(Foo *f, double (Foo::*m)(double d))
{
  (f->*m)(3.0);
}

int main()
{
  Foo f;
  call_using_obj_and_method(&f, &Foo::bar);
  return 0;
}

クラスのインスタンスも必要であることに注意してください。私の例では、これは別のパラメーターですが、グローバル変数、またはクラスFooのシングルトンインスタンスにすることもできます。

ただし、jkpが言ったように、メソッドを静的にするか、通常の関数に変換することで問題を解決することもできます。

編集:あなたの質問を正しく理解しているかどうかはわかりません。ファンクショナルを使う必要はないと思います。これが私の例がObjective-C++でどのように見えるかです:

#include <Cocoa/Cocoa.h>

class Foo
{
  public:
    double bar(double d)
    {
      return d;
    }
};

typedef double (Foo::*fooMethodPtr)(double d);

@interface Baz : NSObject
{
}
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m;
@end

@implementation Baz
- (void)callFooObj:(Foo *)f method:(fooMethodPtr)m
{
  (f->*m)(3.0);
}
@end

int main()
{
  Foo f;
  Baz *b = [[Baz alloc] init];
  [b callFooObj:&f method:&Foo::bar];
  return 0;
}
于 2009-07-27T13:33:57.907 に答える
2

C ++クラスをObjective-Cクラスでラップしてから、

- (void) plotWithObject:(id)obj
{
   double result = [obj evaluate: 1.5];
   // ... etc ...
}

プロットに加えて:メソッド。

于 2009-07-27T13:39:20.987 に答える
1

Expressionここでの問題は、クラスのメンバー関数をObjective-Cクラスに渡そうとしていることだと思います。これはthis、その関数への最初の引数としてポインターを想定しているため、機能しません(したがって、シグネチャはメソッドで期待されるものと同じではありませんplot:

C ++メソッドを静的にすると、これを行うことができますが、標準のC関数を使用することにあまりお金をかけません。

IE、Expressionクラスが次のようになっている場合:

class Expression {
    static double evaluate(double);
}

あなたはそれをこのように呼ぶことができるはずです:

[self plot:myExpression.evaluate(&Express::evalulate)];

ただし、私が言っているように、標準のC関数を使用している可能性があるため(C ++クラスでより便利なことを実行できない場合)、これには大きな価値はありません。

私はかつて、boost :: bind()の結果をobjective-cメソッドでブリッジしようとすることを検討しましたが、それほど遠くはありませんでした。C ++ランタイムを十分に深く掘り下げれば、それは可能だと確信しています。

于 2009-07-27T13:22:45.500 に答える
0

C ++メンバー関数がdoubleを返す場合、コードは次のようになりませんか?

- (void)plot:(double)f;

..。

[self plot:myExpression.evaluate(aDouble)];

または同様のもの。私はObj-CとC++の混合をあまり使用していませんが、これが私がそれにアプローチする方法です。また、Objective-C ++ファイルをそのように混合する場合は、.mm拡張子が必要になる場合があります。

于 2009-07-27T12:26:35.983 に答える
0

インスタンス化されたc++クラスをNSValue内に渡してから、c ++メソッドを直接呼び出さないのはなぜですか?

- (NSValue*)getExpression
{
    Expression* e = new Expression();
    return [[NSValue alloc] initWithPointer:e];
}

- (void)callExpression(NSValue*)expression
{
    Expression* e = [expression pointerValue];
    e->evaluate();
}
于 2021-01-17T11:41:06.393 に答える