Протокол по сравнению с категорией

Как сказал @lubgr в своем ответе, вы должны вернуть unique_ptr не сырой из функции clone. В любом случае, перейдя к вашим вопросам:

  1. Вам нужен конструктор копирования в B? Ну, это зависит от ваших вариантов использования, но если вы копируете объекты класса B, вам может понадобиться один. Но, как вы сказали, вы делаете это довольно часто, поэтому было бы разумнее рассмотреть более общий подход. Один из них будет создавать оболочку для unique_ptr, которая будет иметь конструктор копирования и которая сделает глубокую копию этого указателя в этом конструкторе копирования. Рассмотрим следующий пример:
    template<class T>
    class unique_ptr_wrap {
    public:
        unique_ptr_wrap(std::unique_ptr< T > _ptr) : m_ptr(std::move(_ptr)){}
    
        unique_ptr_wrap(const unique_ptr_wrap &_wrap){
            m_ptr = _wrap->clone();
        }
    
        unique_ptr_wrap(unique_ptr_wrap &&_wrap){
            m_ptr = std::move(_wrap.m_ptr);
        }
    
        T *operator->() const {
            return m_ptr.get();
        }
    
        T &operator*() const {
            return *m_ptr;
        }
    private:
        std::unique_ptr< T > m_ptr;
    };
    
  2. Это снова зависит от ваших потребностей. Я лично рекомендовал бы также перегружать конструктор перемещения, чтобы он использовал менее динамические распределения (но это может быть предварительная оптимизация, которая является корнем всего зла).
36
задан JiteshW 17 September 2013 в 05:39
поделиться

5 ответов

Протокол является тем же самым как интерфейсом в Java: это - по существу контракт, в котором говорится, "Любой класс, который реализует этот протокол, также реализует эти методы".

категория А, с другой стороны, просто связывает методы с классом. Например, в Какао , я могу создать категорию для NSObject, который позволит мне добавлять методы к NSObject класс (и, конечно, все подклассы), даже при том, что у меня действительно нет доступа к NSObject .

Для суммирования: протокол определяет, какие методы класс реализует; категория добавляет методы к существующему классу.

надлежащее использование каждого, тогда, должно быть четким: протоколы Использования для объявления ряда методов, которые класс должен реализовать и использовать категории для добавления методов к существующему классу.

89
ответ дан The iOSDev 27 November 2019 в 05:09
поделиться

В протоколе говорится, "вот некоторые методы, которые я хотел бы Вы реализовать". Категория говорит, "я расширяю функциональность этого класса с этими дополнительными методами".

Теперь, я подозреваю Ваши основы беспорядка от использования Apple фразы "неофициальный протокол". Вот ключ (и наиболее сбивающий с толку) точка: неофициальный протокол является на самом деле не протоколом вообще. Это - на самом деле категория на NSObject. Какао использует неофициальные протоколы глубоко для обеспечения интерфейсов для делегатов. Начиная с @protocol синтаксис не позволил дополнительные методы, пока Objective C 2.0, Apple не реализовала дополнительные методы, чтобы ничего не сделать (или возвратить фиктивное значение) и требуемые методы выдать исключение. Не было никакого способа осуществить это через компилятор.

Теперь, с Objective C 2.0, @protocol синтаксис поддерживает @optional ключевое слово, отмечая некоторые методы в протоколе как дополнительные. Таким образом Ваш класс соответствует протоколу, пока он реализует все методы, отмеченные как @required. Компилятор может определить, реализует ли Ваш класс все требуемые методы также, который экономит время. iPhone SDK исключительно использует Objective C 2.0 @protocol синтаксис, и я не могу думать о серьезном основании не использовать его в любой новой разработке (за исключением приложений Какао Mac OS X, которые должны работать на более ранних версиях Mac OS X).

29
ответ дан Alex 27 November 2019 в 05:09
поделиться

Категории:

категория А является способом добавить новые методы ко всем экземплярам существующего класса, не изменяя сам класс.

Вы используете категорию, когда Вы хотите добавить функциональность к существующему классу, не происходя из того класса или переписывая исходный класс.

Скажем, Вы используете NSView объекты в какао, и Вам жаль, что все экземпляры NSView не смогли выполнить некоторое действие. Очевидно, Вы не можете переписать NSView класс, и даже если Вы произойдете из него, не весь из NSView, то объекты в Вашей программе будут иметь Ваш производный тип. Решение состоит в том, чтобы создать категорию на NSView, который Вы тогда используете в своей программе. Пока Вы #import заголовочный файл, содержащий Ваше объявление категории, появится, как будто каждый NSView объект отвечает на методы, которые Вы определили в исходном файле категории.

Протоколы:

протокол А является набором методов, которые любой класс может принять решение реализовать.

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

Это может быть полезно при создании семьи подобных классов что вся потребность связаться с общим классом "контроллера". Коммуникация между классом контроллера и управляемыми классами может все быть упакована в отдельный протокол.

примечание Стороны: объективный язык C не поддерживает множественное наследование (класс может только произойти из одного суперкласса), но большая часть той же функциональности может быть обеспечена протоколами, потому что класс может соответствовать нескольким различным протоколам.

16
ответ дан e.James 27 November 2019 в 05:09
поделиться

К моему пониманию Протоколы немного похожи на Интерфейсы Java. Протоколы объявляют методы, но реализация до каждого класса. Категории, кажется, что-то как mixins Ruby. С Категориями можно добавить методы к существующим классам. Даже встроенные классы.

5
ответ дан PEZ 27 November 2019 в 05:09
поделиться

Протоколы являются контрактами для реализации указанных методов. Любой объект, который соответствует протоколу, соглашается обеспечить реализации для тех методов. Хорошее использование протокола должно было бы определить ряд методов обратного вызова для делегата (где делегат должен ответить на все методы).

Категории обеспечивают способность расширить текущий объект путем добавления методов к нему (методы класса или методы экземпляра). Хорошее использование для категории расширило бы класс NSString для добавления функциональности, которая не была там прежде, такие как добавление метода для создания новой строки, которая преобразовывает получатель в 1337 5P34K.

NSString *test = @"Leet speak";
NSString *leet = [test stringByConvertingToLeet];
1
ответ дан dreamlax 27 November 2019 в 05:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: