Метод считывания и метод set, указатели или ссылки и хороший синтаксис для использования в C++?

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

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

решение этого состоит в том, чтобы переехать, как Вы делаете оценки - для всех. Разработчики могут быть плохими при оценке абсолютного времени, но они довольно хороши в относительное время. Таким образом в понедельник, вместо, "сколько времени это возьмет для добавления whoosiwhatsit?", спросите, "что Вы можете быть сделаны на whoosiwhatsit меньше чем через неделю?" Это становится их задачей в течение недели.

В следующий понедельник Вы смотрите на то, как это пошло. "Ну, Я установил floogle за два дня, но оказывается, что это повлияло на mcphee... поэтому на этой неделе я должен разъединить тех парней, таким образом, whoosiwhatsit файлы не становятся перезаписанными". Хорошо, существует их задача в течение недели.

Вы могли бы думать, что это не поможет, потому что Вы все еще не знаете, когда whoosiwhatsit будет готовым. Это правда. У Вас есть два варианта здесь:

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

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

10
задан dmckee 5 September 2010 в 19:55
поделиться

8 ответов

Как общий закон:

  • Если NULL является допустимым параметром или возвращаемым значением, используйте указатели.
  • Если NULL является НЕ допустимым параметром или возвращаемым значением , используйте ссылки.

Итак, если сеттер, возможно, должен вызываться с NULL, используйте указатель в качестве параметра. В противном случае используйте ссылку.

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

15
ответ дан 3 December 2019 в 14:00
поделиться

Джонатан, какой компилятор вы используете? Есть большая вероятность, что shared_ptr уже поставляется с ним как часть реализации TR1 компилятора.

0
ответ дан 3 December 2019 в 14:00
поделиться

В дополнение к другим ответам, если вы выберете ссылки для получателя, не t напишите это, как в вашем примере:

YourClass &Member(){
   return *this->pMember;
}

Ваш геттер фактически разрешает установку, как в instance-> Member () = YourClass (); и, таким образом, обходит ваш установщик. Это может быть запрещено, если YourClass не копируется, но это еще одна вещь, о которой следует помнить. Другой недостаток - геттер не является константой.

Вместо этого напишите свой получатель следующим образом:

const YourClass &Member() const {
   return *this->pMember;
}
2
ответ дан 3 December 2019 в 14:00
поделиться

Ваш код выглядит так, как будто вы привыкли к другому языку - в C ++ использование this-> x (например) относительно необычно. Когда код вообще хорошо написан, используется аксессор или мутатор.

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

Когда / если вам нужно контролировать, какое значение назначен, перегрузка оператора позволяет вам взять этот контроль, не заставляя уродливый синтаксис получения / установки в клиентском коде. В частности, вам нужен прокси-класс (или шаблон класса). Просто для одного примера, одна из наиболее распространенных ситуаций, когда людям нужны функции get / set, - это что-то вроде числа, которое должно быть ограничено определенным диапазоном. setXXX проверяет, находится ли новое значение в диапазоне, а getXXX возвращает значение.

Если вы этого хотите, (довольно) простой шаблон может сделать гораздо больше. чисто:

template <class T, class less=std::less<T> >
class bounded {
    const T lower_, upper_;
    T val_;

    bool check(T const &value) {
        return less()(value, lower_) || less()(upper_, value);
    }

    void assign(T const &value) {
        if (check(value))
            throw std::domain_error("Out of Range");
        val_ = value;
    }

public:
    bounded(T const &lower, T const &upper) 
        : lower_(lower), upper_(upper) {}

    bounded(bounded const &init) 
        : lower_(init.lower), upper_(init.upper)
    { 
        assign(init); 
    }

    bounded &operator=(T const &v) { assign(v);  return *this; }

    operator T() const { return val_; }

    friend std::istream &operator>>(std::istream &is, bounded &b) {
        T temp;
        is >> temp;

        if (b.check(temp))
            is.setstate(std::ios::failbit);
        else
            b.val_ = temp;
        return is;
    }
};

Это также делает код намного ближе к самодокументированию - например, когда вы объявляете объект вроде: bounded (1, 1024); , сразу становится очевидным, что намерение является целым числом в диапазоне от 1 до 1024. Единственная часть, которую кто-то может найти под вопросом, - это то, входит ли 1 и / или 1024 в диапазон. Это значительно отличается от определения int в классе и ожидания, что каждый, кто когда-либо смотрит на класс, поймет, что они должны использовать setXXX для обеспечения некоторого (на тот момент неизвестного) набора границ для значений, которые могут быть назначено.

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

и ожидая, что все, кто когда-либо посмотрит на класс, поймут, что они должны использовать setXXX для обеспечения некоторого (на тот момент неизвестного) набора границ для значений, которые могут быть назначены.

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

и ожидая, что все, кто когда-либо посмотрит на класс, поймут, что они должны использовать setXXX для обеспечения некоторого (на тот момент неизвестного) набора границ для значений, которые могут быть назначены.

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

предполагается использовать setXXX для принудительного применения некоторого (на тот момент неизвестного) набора границ для значений, которые могут быть присвоены.

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

предполагается использовать setXXX для принудительного применения некоторого (на тот момент неизвестного) набора границ для значений, которые могут быть присвоены.

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

Нет никакого реального аргумента в пользу синтаксиса - вы просто присваиваете общедоступную переменную, как и любую другую - с незначительной детализацией, заключающейся в том, что попытка присвоить значение, выходящее за пределы допустимого диапазона, вызовет исключение. Теоретически класс, вероятно, должен принимать параметр-шаблон политики, чтобы точно указывать, что он делает в этом случае, но у меня никогда не было реальной причины беспокоиться об этом.

Нет никакого реального аргумента по поводу синтаксиса - вы просто присваиваете общедоступную переменную, как и любую другую - с небольшой детализацией, заключающейся в том, что попытка присвоить значение, выходящее за пределы допустимого диапазона, вызовет исключение. Теоретически класс, вероятно, должен принимать параметр-шаблон политики, чтобы точно указывать, что он делает в этом случае, но у меня никогда не было реальной причины беспокоиться об этом.

7
ответ дан 3 December 2019 в 14:00
поделиться

Лучше всего предоставить клиенту реальный объектно-ориентированный интерфейс, скрывающий детали реализации. Геттеры и сеттеры не являются ОО.

7
ответ дан 3 December 2019 в 14:00
поделиться

в чем разница между ними?

Ссылка - это псевдоним вещи (это это вещь *). Указатель - это адрес вещи. Если есть шанс, что то, на что указывает, не будет, тогда вы, вероятно, не захотите возвращать ссылки. Ссылки говорят вызывающему: «Я дам вам псевдоним, который будет существовать, когда я верну его вам». На самом деле нет никакого способа проверить ссылку, чтобы узнать, действительно ли то, что лежит в основе.

С помощью указателя семантически вы подразумеваете, что вызывающий может пожелать проверить, существует ли элемент Member перед его использованием. Обычно это делается с проверкой NULL.

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

2
ответ дан 3 December 2019 в 14:00
поделиться

+1, чтобы задать вопрос об использовании сеттеров и геттеров. Если вы должны их использовать и иметь возможность нулевого значения, рассмотрите возможность использования boost :: shared_ptr. Таким образом, владение осуществляется за вас.

1
ответ дан 3 December 2019 в 14:00
поделиться

Как говорили другие, используйте указатели, если возможно значение null.

В большинстве случаев , По возможности я предпочитаю использовать ссылки. Лично в моем коде мне нравится использовать различие между указателями и ссылками для обозначения владения сигналом. Я думаю, что вызовы со ссылками - это «одалживание» объекта другой функции или классу. Исходный класс, который передал или вернул ссылку, по-прежнему владеет ею и отвечает за ее создание, обслуживание и очистку. Когда мой код передает неконстантный указатель, с другой стороны, это обычно означает, что происходит какая-то передача или разделение прав собственности со всеми вытекающими отсюда обязанностями.

(И да, я обычно использую умные указатели . Это похоже на ссылки в моей голове. Я говорю о коде более низкого уровня, чем здесь.)

Мне нравится использовать различие между указателями и ссылками для обозначения владения сигналом. Я думаю, что вызовы со ссылками - это «одалживание» объекта другой функции или классу. Исходный класс, который передал или вернул ссылку, по-прежнему владеет ею и отвечает за ее создание, обслуживание и очистку. С другой стороны, когда мой код передает неконстантный указатель, это обычно означает, что происходит какая-то передача или разделение прав собственности со всеми вытекающими отсюда обязанностями.

(И да, я обычно использую умные указатели . Это похоже на ссылки в моей голове. Я говорю о коде более низкого уровня, чем здесь.)

Мне нравится использовать различие между указателями и ссылками для обозначения владения сигналом. Я думаю, что вызовы со ссылками - это «одалживание» объекта другой функции или классу. Исходный класс, который передал или вернул ссылку, по-прежнему владеет ею и отвечает за ее создание, обслуживание и очистку. С другой стороны, когда мой код передает неконстантный указатель, это обычно означает, что происходит какая-то передача или разделение прав собственности со всеми вытекающими отсюда обязанностями.

(И да, я обычно использую умные указатели . Это похоже на ссылки в моей голове. Я говорю о коде более низкого уровня, чем здесь.)

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

(И да, я обычно использую умные указатели . Это похоже на ссылки в моей голове. Я говорю о коде более низкого уровня, чем здесь.)

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

(И да, я обычно использую умные указатели . Это похоже на ссылки в моей голове. Я говорю о коде более низкого уровня, чем здесь.)

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

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