我发现分配块对于 Objective-C 类参数和 C++ 类参数的行为不同。
想象一下,我有这个简单的 Objective-C 类层次结构:
@interface Fruit : NSObject
@end
@interface Apple : Fruit
@end
然后我可以写这样的东西:
Fruit *(^getFruit)();
Apple *(^getApple)();
getFruit = getApple;
这意味着,对于 Objective-C 类,块的返回类型是协变的:返回更具体的块可以看作是返回更一般的块的“子类”。在这里,getApple
可以将传递苹果的区块安全地分配给getFruit
区块。事实上,如果以后使用,Apple *
当您期待Fruit *
. 而且,从逻辑上讲,反过来是行不通的:getApple = getFruit;
不编译,因为当我们真的想要一个苹果时,我们不高兴只得到一个水果。
同样,我可以这样写:
void (^eatFruit)(Fruit *);
void (^eatApple)(Apple *);
eatApple = eatFruit;
这表明块的参数类型是协变的:可以处理更一般的参数的块可以用于需要处理更具体的参数的块。如果一个块知道如何吃水果,它也会知道如何吃苹果。同样,反之亦然,这将无法编译:eatFruit = eatApple;
.
这一切都很好——在 Objective-C 中。现在让我们在 C++ 或 Objective-C++ 中尝试一下,假设我们有这些类似的 C++ 类:
class FruitCpp {};
class AppleCpp : public FruitCpp {};
class OrangeCpp : public FruitCpp {};
可悲的是,这些块分配不再编译:
FruitCpp *(^getFruitCpp)();
AppleCpp *(^getAppleCpp)();
getFruitCpp = getAppleCpp; // error!
void (^eatFruitCpp)(FruitCpp *);
void (^eatAppleCpp)(AppleCpp *);
eatAppleCpp = eatFruitCpp; // error!
Clang 抱怨“从不兼容的类型分配”错误。因此,对于 C++ 类,块在返回类型和参数类型方面似乎是不变的。
这是为什么?我对 Objective-C 类提出的相同论点不也适用于 C++ 类吗?我错过了什么?