我有一个C ++类“Expression
”,其中包含我想在Objective-C类“GraphVC
”中使用的方法。
class Expression {
double evaluate(double);
}
我的Objective-C课程:
@implementation GraphVC : UIViewController {
- (void)plot:(double(*)(double))f;
@end
我认为传递带有double并返回double的函数指针是最容易的,而不是C ++对象,但是使用functional.h
并没有取得多大成功。使用Objective-C的C ++方法的最佳方法是什么?
编辑:感谢您的快速回复。请允许我详细说明......我有一个用C ++编写的后端,我操作Expression类型的对象。有理性,多项式,单项式等的子类。我最初的想法是使用mem_fun,但我无法通过这种方式编译代码。我也无法使用bind1st来绑定this
指针。
evaluate()
函数,我也不想打破后端和iPhone GUI类之间的清晰分离。 / LI>
Expression
个实例。我应该更明确地声明我需要将一个C ++成员函数(不是静态函数或现有的C函数)传递给Objective-C对象。有没有人幸运使用C ++的<functional>
将成员函数转换为我可以在Objective-C对象中使用的指针,还是应该使用Objective-C包装器?
答案 0 :(得分: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;
}
答案 1 :(得分:2)
我建议在Objective-C类中包装C ++类,然后提供
- (void) plotWithObject:(id)obj
{
double result = [obj evaluate: 1.5];
// ... etc ...
}
除了情节:方法。
答案 2 :(得分:1)
我认为这里的问题是你试图将Expression
类的成员函数传递给Objective-C类。这不起作用,因为它期望this
指针作为该函数的第一个参数(因此签名与plot:
方法所期望的签名不同。
如果你使C ++方法成为静态的,你就可以做到这一点,但是你不会因为使用标准的C函数而自行购买。
IE,如果Expression
类看起来像这样:
class Expression {
static double evaluate(double);
}
您应该可以这样称呼它:
[self plot:myExpression.evaluate(&Express::evalulate)];
正如我所说,这里没有太大的价值,因为你也可以使用标准的C函数(除非你可以在C ++类中做一些对你更有用的东西)。
我曾经尝试过使用objective-c方法尝试桥接boost :: bind()结果但是没有达到很远。我敢肯定,如果你在C ++运行时深入挖掘,你可以做到这一点。
答案 3 :(得分:0)
如果您的C ++成员函数返回一个double,那么您的代码不能只是这样吗?
- (void)plot:(double)f;
...
[self plot:myExpression.evaluate(aDouble)];
或类似的东西。我没有太多混合使用Obj-C和C ++,但这就是我接近它的方法。你也可能必须在Objective-C ++文件上加一个.mm扩展名,如果你这样混合它们。
答案 4 :(得分:0)
为什么不在 NSValue 内部传递实例化的 c++ 类,然后直接调用 c++ 方法?
- (NSValue*)getExpression
{
Expression* e = new Expression();
return [[NSValue alloc] initWithPointer:e];
}
- (void)callExpression(NSValue*)expression
{
Expression* e = [expression pointerValue];
e->evaluate();
}