Виртуальное ключевое слово заставляет компилятор выбрать реализацию метода, определенную в классе объекта, а не в классе указателя.
Shape *shape = new Triangle();
cout << shape->getName();
В приведенном выше примере Shape :: getName будет вызываться по умолчанию, если getName () не определен как виртуальный в Shape Base. Это заставляет компилятор искать реализацию getName () в классе Triangle, а не в классе Shape.
Виртуальная таблица - это механизм, в котором компилятор отслеживает различные реализации виртуальных методов подклассов. Это также называется динамической отправкой, а - связанными с ней некоторыми служебными данными.
Наконец, почему виртуальный даже необходим в C ++, почему бы не сделать его поведением по умолчанию, как на Java?
Аргумент stop
для блока позволяет вам преждевременно остановить перечисление . Это эквивалент break
из нормального цикла for
. Вы можете игнорировать его, если хотите пройти через каждый объект в массиве.
for( id obj in arr ){
if( [obj isContagious] ){
break; // Stop enumerating
}
if( ![obj isKindOfClass:[Perefrigia class]] ){
continue; // Skip this object
}
[obj immanetizeTheEschaton];
}
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if( [obj isContagious] ){
*stop = YES; // Stop enumerating
return;
}
if( ![obj isKindOfClass:[Perefrigia class]] ){
return; // Skip this object
}
[obj immanentizeTheEschaton];
}];
Это параметр out, потому что это ссылка на переменную из области вызова. Он должен быть установлен внутри вашего блока, но читается внутри enumerateObjectsUsingBlock:
, так же NSError
s обычно передаются обратно в ваш код из вызовов инфраструктуры.
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
// N.B: This is probably not how this method is actually implemented!
// It is just to demonstrate how the out parameter operates!
NSUInteger idx = 0;
for( id obj in self ){
BOOL stop = NO;
block(obj, idx++, &stop);
if( stop ){
break;
}
}
}