Я пишу математическую библиотеку в Objective-C (для удовольствия), и теперь мне нужно каким-то образом эмулировать перегрузку функций в стиле C++.Перегрузка метода эмуляции в Objective-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
и реализовать перегруженный метод, с помощью создания кодированного имени методы и назовите его.
Любые лучшие идеи?
EDIT
Вот моя перегружать логика:
@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
EDIT 2
Базовый класс для библиотеки "перегрузки" является NSProxy
, так что пользователи библиотеки не могут создать экземпляр.
EDIT 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
Создание класса для каждой операции является сумасшедшим! Если вам действительно нужна перегрузка оператора, и вы должны это тщательно изучить, одним из способов было бы указать аргументы вашего метода как типа 'id'. Затем вы можете использовать 'isKindOfClass:', чтобы точно определить, что вам нужно делать с ними. – bdesham
@bdesham Ну этот «один класс для каждой перегрузки» предназначен для использования с категориями классов, так что позже могут быть добавлены различные перегрузки. –