Где аргумент BOOL * для enumerateObjectsUsingBlock: created? [Дубликат]

Виртуальное ключевое слово заставляет компилятор выбрать реализацию метода, определенную в классе объекта, а не в классе указателя.

Shape *shape = new Triangle(); 
cout << shape->getName();

В приведенном выше примере Shape :: getName будет вызываться по умолчанию, если getName () не определен как виртуальный в Shape Base. Это заставляет компилятор искать реализацию getName () в классе Triangle, а не в классе Shape.

Виртуальная таблица - это механизм, в котором компилятор отслеживает различные реализации виртуальных методов подклассов. Это также называется динамической отправкой, а - связанными с ней некоторыми служебными данными.

Наконец, почему виртуальный даже необходим в C ++, почему бы не сделать его поведением по умолчанию, как на Java?

  1. C ++ основан на принципах «Zero Overhead» и «Платите за то, что вы используете». Поэтому он не пытается выполнять динамическую отправку для вас, если вам это не нужно.
  2. Чтобы обеспечить больший контроль над интерфейсом. Делая функцию не виртуальной, интерфейс / абстрактный класс может управлять поведением во всех его реализациях.
77
задан Mick MacCallum 28 October 2012 в 08:36
поделиться

1 ответ

Аргумент 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;
        }
    }
}
145
ответ дан Josh Caswell 26 August 2018 в 12:38
поделиться