Имеет ли смысл предоставить неконтролируемую референцию
Вопрос
Иногда мне нужно разоблачить некоторые члены класса. Например, в следующем примере class Mechanic
может потребоваться прямой доступ к Engine
составная часть. Я прочитал много раз, что все поля должны быть доступны методами Mutator (Accessor) из-за нескольких причин. Но есть ли преимущество при предоставлении справки не-постоянного Getter:
class Car
{
public:
Engine & engine()
{
return m_engine;
}
//as a consequence you will also need to provide const version
const Engine & engine() const
{
return m_engine;
}
private:
Engine m_engine;
}
за то, что просто выдвигает компонент двигателя общественностью:
class Car
{
public:
Engine engine;
}
Вы также можете заменить public
с protected
Если вам не нравится этот пример. В реальной жизни у вас есть что -то момиллар на Java, когда дело доходит до System.in
или System.out
. Отказ Похоже, что чтобы быть полностью соответствующим тому, что говорят некоторые люди, вам нужно будет выполнять такие звонки, как System.getInstance().getOut().println("hello world")
. Отказ Я не вижу никакой выгоды, кроме большого количества бюрократического кода в таких случаях.
Решение 5
Я нашел разумную точку зрения, чтобы обеспечить такой Getter. Это облегчает интеграцию вашего программного обеспечения (например, когда вы хотите перевести интерфейс на другой язык и связать ABIS).
Другие советы
Они могут быть полезны, когда значение, которое вы возвращаете, на самом деле на куче.
template<class T> class Singleton
{
private:
static T* m_pSingleton;
public:
T& getSingleton() { assert(m_pSingleton); return(*m_pSingleton); };
}; // eo class Singleton
Явные полученные и сортировки могу быть чрезмерно бюрократическим; Это зависит от вашей ситуации.
Основная цитируемая причина для имения функций Getter и Setter состоит в том, что она выделяет клиентов вашего класса от потенциальных изменений в реализации в будущем (например, считают, что произойдет, если вы решите сгенерировать Engine
Объект по требованию (а не использовать переменную члена) или решите скрыть ее за умным указателем или каким -либо другим контейнером).
Если ваш класс, если очень простой (например, близок к тому, чтобы быть Капсул) и вряд ли изменится, тогда может не стоить того, чтобы внедрить Getters и Setters.
Однако, чтобы ответить на ваш вопрос, неконфсайт Геттер, вероятно, не имеет большого смысла. Ваш прототип Getter должен быть Engine & engine() const
; в противном случае вы не сможете это вызвать const
Car
объекты.
Одним из преимуществ предоставления Getter является то, что когда и если вы решите изменить способ работы Getter, код, который использует этот класс, не должен быть перекомпилирован. Но если у вас есть общедоступное поле, а затем решите сделать получение, весь код должен быть перекомпилирован. Кроме этого, я не вижу серьезной практической причины, чтобы сделать вашу переменную частной. Однако обратите внимание, что все это содержится тогда и только тогда, когда вам нужно предоставить внешним пользователям, чтобы получить ссылку на двигатель. Если можно разработать программное обеспечение, чтобы это было устранено вообще, это будет лучше.
Как я уже оказался, чтобы получить образование в последнее время, Getter и Citners запах плохого дизайна. Но, если вы хотите это таким образом, предоставляя функции, чтобы получить и установить m_engine
(Определяется вами), а не просто разоблачать его (у вас нет вмешательства) означает, что у вас есть пункт плагина для будущих изменений.
Для меня это имеет смысл здесь:
image(i,j) = 234;
Вместо того, чтобы думать о разоблачении частных членов класса, подумайте по поводу линий методов вызова на те классы. Я читаю интересную статью Java, Почему методы получения и сеттера злые, который применяется как можно больше к C ++, как это делает с Java.
Да, это имеет смысл - для обслуживания, проверки и последовательности.
Возможно, вам понадобится изменить многие аспекты класса в будущем, предоставление аксессы может помочь минимизировать поломку клиентского кода.
Вы можете ввести всю необходимую вам логику проверки, чтобы гарантировать, что двигатель является допустимым указателем, не в непригодном состоянии и т. Д.
Наконец, ваш код будет последовательным: вам не придется открывать заголовок, чтобы узнать видимость члена - вы просто всегда знаете. Это также полезно с шаблонами.
В этом случае вам скорее нужно Car.fix(const Mechanic&)
функция, которая затем дает двигатель к Mechanic
, сказать: Engine.fix(const Mechanic&)
, как я полагаю, состояние Engine
будет модифицирован.
Первоначальная идея использования классов заключалась в том, чтобы связать данные с его функциями доступа. Если вы делаете Setter или Getter, который просто возвращает внутренние данные, это означает, что ваши данные не связаны вместе с его функциональностью доступа: ваш класс не завершен.
Вы хотите только подвергать новые данные, которые выделяют класс. Отказ Сказать Car.get_exhaust()
и то Car
Не имеет выхлопа, только это дает, когда вы запрашиваете это. ;)
Или Fire Riefle.fire()
тогда как нет доступа для Riefle::Trigger
будет зафиксирована механикой, как SO: Trigger.fix_by(Mechanic)
А потом fix_by
позвоню скажет Mechanic.add_working_hour(0.5)
. Отказ XD