objective-c ++: можно ли определить класс c ++ с помощью метода, который возвращает классы objective-c и использует ковариантные результаты?

** Изменить: это происходит только с llvm; gcc прекрасно это поддерживает.

Обратите внимание на следующее.

Objective-c классы A и B.

B является подклассом A.

Мы хотим, чтобы иерархия C ++ выглядела так:

class X {
  //...
  public:
    virtual A* getFoo();
};
class Y : public X {
  //...
  public:
    B* getFoo();
};

Однако, если вы сделаете это, вы получите ошибку, поскольку типы Objective-c сбивают компилятор c ++ с толку:

error: virtual function 'getFoo' has a different return type ('Y *') than the function it overrides (which has return type 'X *')

Мне интересно, есть ли у кого-нибудь обходной путь для этого? (Очевидно, что в долгосрочной перспективе мы будем отходить от классов Objective-c, но это не сегодня).

P.S. Это кажется как самый похожий вопрос, который я мог найти, но я почти уверен, что это другая проблема.


person Benjamin Horstman    schedule 06.07.2011    source источник


Ответы (1)


Это компилируется и отлично работает для меня:

#import <Cocoa/Cocoa.h>

@interface A : NSObject

- (NSString*) bar;

@end

@implementation A

- (NSString*) bar
{
    return @"";
}

@end

@interface B : A
@end

@implementation B

- (NSString*) bar
{
    return @"!!!";
}

@end

class X {
  //...
  public:
    virtual A* getFoo() = 0;
};

class Y : public X {
  //...
  public:
    virtual B* getFoo() { return [B new]; }
};


int main (int argc, char const *argv[])
{
    X* x = new Y;
    NSLog(@"%@", [x->getFoo() bar]);  // >> !!!

    return 0;
}

Может быть, ваша проблема заключалась в том, что вы не импортировали файл заголовка B в файл, определяющий Y? Вы не можете получить ковариацию (по крайней мере, в C ++) для неполных классов, поскольку компилятор должен знать, что B наследуется от A, чтобы скомпилировать Y.

В любом случае, отвечая на ваш вопрос, похоже, это возможно.

person Chris Devereux    schedule 07.07.2011
comment
Ах, это происходит только с llvm: / Я обновил вопрос, но я полагаю, что настоящий ответ здесь - сообщить об ошибке для llvm: llvm.org/bugs/show_bug.cgi?id=10309 - person Benjamin Horstman; 08.07.2011
comment
Если вы не можете переключить g ++ обратно, пока это не будет исправлено, я думаю, вы можете вернуть id в качестве обходного пути. - person Chris Devereux; 09.07.2011