Как я называю метод set свойства от __ init __

Более подробный, чем Meyers, но я мог бы сделать это:

class X {

    private:

    // This method MUST NOT be called except from boilerplate accessors.
    Z &_getZ(size_t index) const {
        return something;
    }

    // boilerplate accessors
    public:
    Z &getZ(size_t index)             { return _getZ(index); }
    const Z &getZ(size_t index) const { return _getZ(index); }
};

закрытый метод имеет нежелательное свойство, что это возвращает неконстанту Z& для экземпляра константы, который является, почему это является частным. Закрытые методы могут повредить инварианты внешнего интерфейса (в этом случае, желаемый инвариант является "объектом константы, не может быть изменен через ссылки, полученные через него к объектам, которые это имеет -").

Примечание, что комментарии являются частью шаблона - интерфейс _getZ, определяет, что это никогда не допустимо для вызова его (кроме средств доступа, очевидно): нет никакого мыслимого преимущества для выполнения так так или иначе, потому что это - еще 1 символ для ввода и не приведет к меньшему или более быстрому коду. Вызов метода эквивалентен вызову одного из средств доступа с const_cast, и Вы не хотели бы делать это также. Если Вы волнуетесь по поводу совершения очевидных ошибок (и это - справедливая цель), то назовите его const_cast_getZ вместо _getZ.

Между прочим, я ценю решение Meyers. У меня нет философского возражения на него. Лично, тем не менее, я предпочитаю крошечный бит управляемого повторения и закрытый метод, который нужно только назвать в определенных плотно-контролируемых-условиях по методу, который похож на шум в линии. Выберите свой яд и придерживайтесь его.

[Редактирование: Kevin справедливо указал, что _getZ мог бы хотеть звонить, дальнейший метод (скажите, генерирует), который специализирован на константе таким же образом getZ. В этом случае _getZ видел бы константу Z& и имейте к const_cast его перед возвратом. Это все еще безопасно, так как шаблонное средство доступа управляет всем на основе политик, но не исключительно очевидно, что это безопасно. Кроме того, если Вы делаете это, и затем более позднее изменение генерирует, чтобы всегда возвратить константу, тогда также необходимо изменить getZ, чтобы всегда возвратить константу, но компилятор не скажет Вам, что Вы делаете.

, Что последняя точка о компиляторе также верна для рекомендуемого шаблона Meyers, но первая точка о неочевидном const_cast не. Так в итоге я думаю что, если _getZ, оказывается, нужен const_cast для его возвращаемого значения, то этот шаблон теряет много своего значения по Meyers. Так как это также переносит недостатки по сравнению с Meyers, я думаю, что переключился бы на его в той ситуации. Рефакторинг от одного до другого легок - это не влияет ни на какой другой допустимый код в классе, так как только недопустимый код и шаблон называют _getZ.]

10
задан smci 22 August 2012 в 02:16
поделиться

1 ответ

Свойство является дескриптором, и дескрипторы работают только с классами нового стиля. Попробуйте:

class User(object): ...

вместо:

class User: ...

Хорошее руководство по дескрипторам можно найти здесь .

14
ответ дан 3 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

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