我是一个爱好者,正在用Objective-C编写数学库,现在我需要一种方式来模拟C++风格的函数重载。
我的预期效果:
NSNumber *x = @(25);
CMVector *v = [CMVector vectorWithElements:@12, @14, @18, nil];
CMMatrix *m = [CMMatrix matrixWithRows:@[@12, @13, @0 ],
@[@24, @26, @30],
@[@0, @0, @1 ], nil];
CMMatrix *i = [CMMatrix identityMatrixWithRank:3];
NSLog(@"%@ %@ %@ %@", [x multiply:v], [x multiply:m], [m multiply: i], [v multiply:x]);
有没有实现这个的方法?
我想到了一种可能的方法,使用一个类来表示一个重载函数,并将参数名编码到类方法名中,例如:
@interface CMMultiply : NSProxy
+ (NSNumber *)NSNumber:(NSNumber *)left NSNumber:(NSNumber *)right;
+ (CMVector *)NSNumber:(NSNumber *)left CMVector:(CMVector *)right;
+ (CMVector *)CMVector:(CMVector *)left NSNumber:(NSNumber *)right;
+ (CMVector *)CMVector:(CMVector *)left CMVector:(CMVector *)right;
+ (CMMatrix *)NSNumber:(NSNumber *)left CMMatrix:(CMMatrix *)right;
+ (CMMatrix *)CMMatrix:(CMMatrix *)left NSNumber:(NSNumber *)right;
+ (CMMatrix *)CMMatrix:(CMMatrix *)left CMMatrix:(CMMatrix *)right;
@end
通过创建编码后的方法名称并调用它来实现重载方法。您有更好的想法吗?
编辑:以下是我的重载逻辑:
@implementation NSObject (CMOverloading)
- (NSString *)overloadingClassName
{
return NSStringFromClass([self class]); // Override this to handle class clusters
}
- (id)callOverloadedMethod:(Class)method withObject:(id)other
{
NSString *methodName = [NSString stringWithFormat:@"%@:%@:", [self overloadingClassName], [other overloadingClassName]];
SEL selector = NSSelectorFromString(methodName);
return objc_msgSend(method, selector, self, other);
}
@end
编辑2
“重载库”的基类是NSProxy
,因此该库的用户无法实例化它。
编辑3
实现简化宏:
#define CMOverloadingMethod(_return, _left, _right) \
+ (_return *)_left:(_left *)left _right:(_right *)right
#define CMOverloadedMethod(_type, _object) \
return [self callOverloadedMethod:[_type class] withObject:(_object)]
重载方法仍需要一个(简单的)单一实现,在这里,可以直接在NSObject
中实现:
- (id)multiply:(id)right
{
CMOverloadedMethod(CMMultiply, right);
}
并通过 NSNumber
实现它:
@implementation CMMultiply (NSNumber)
CMOverloadingMethod(NSNumber, NSNumber, NSNumber)
{
return @([left doubleValue] * [right doubleValue]);
}
@end
isKindOfClass:
来确定您需要对它们执行的操作。 - bdesham