Я должен предпочесть указатели или ссылки в членских данных?

Поскольку android:backgroundTint не работает под Android API 21, вам нужно использовать app:backgroundTint.

126
задан TemplateRex 17 April 2012 в 16:51
поделиться

8 ответов

Как насчет того, чтобы взять книгу по функциям стандартной библиотеки C?

В противном случае вы можете попробовать страницы руководства: man 3 logf , например

предотвращение реализации оператора присваивания) и не дают преимуществ по сравнению с тем, что может предоставить класс.

Примеры проблем:

  • вы вынуждены инициализировать ссылку в каждом списке инициализаторов конструктора: нет способа вынести эту инициализацию в другая функция ( до C ++ 0x, в любом случае edit: C ++ теперь имеет делегирующие конструкторы )
  • ссылка не может быть восстановлена ​​или иметь значение NULL. Это может быть преимуществом, но если код когда-либо потребуется изменить, чтобы разрешить повторную привязку или чтобы член был нулевым, все виды использования члена должны измениться
  • , в отличие от элементов-указателей, ссылки не могут быть легко заменены интеллектуальными указателями или итераторы, поскольку для рефакторинга может потребоваться
  • Всякий раз, когда используется ссылка, она выглядит как тип значения (. оператор и т. д.), но ведет себя как указатель (может болтаться) - поэтому, например, Google Style Guide не одобряет его
53
ответ дан 24 November 2019 в 00:52
поделиться

Мое практическое правило:

  • Используйте ссылочный член, если вы хотите, чтобы срок службы вашего объекта зависел от жизни других объектов : это явный способ сказать что вы не позволяете объекту существовать без действительного экземпляра другого класса - из-за отсутствия присваивания и обязательства получить инициализацию ссылок через конструктор. Это хороший способ спроектировать свой класс, не предполагая, что его экземпляр является членом другого класса или не принадлежит ему. Вы только предполагаете, что их жизни напрямую связаны с другими случаями. Это позволяет вам позже изменить способ использования экземпляра класса (с новым, в качестве локального экземпляра, в качестве члена класса, сгенерированного пулом памяти в диспетчере и т. Д.)
  • Используйте указатель в других случаях : Если вы хотите, чтобы член был изменен позже, используйте указатель или константный указатель, чтобы быть уверенным, что вы читаете только указанный экземпляр. Если предполагается, что этот тип копируемый, вы все равно не можете использовать ссылки. Иногда вам также необходимо инициализировать член после вызова специальной функции (например, init ()), и тогда у вас просто нет выбора, кроме как использовать указатель. НО: используйте утверждения во всех функциях-членах, чтобы быстро обнаружить неправильное состояние указателя!
  • В тех случаях, когда вы хотите, чтобы время жизни объекта зависело от времени жизни внешнего объекта, и вам также нужно, чтобы этот тип можно было копировать, тогда использовать элементы-указатели, но ссылочный аргумент в конструкторе Таким образом вы указываете при построении, что время жизни этого объекта зависит от аргумента ' s время жизни, НО реализация использует указатели, чтобы их можно было копировать. Пока эти члены изменяются только копией, а у вашего типа нет конструктора по умолчанию, тип должен соответствовать обеим целям.
141
ответ дан 24 November 2019 в 00:52
поделиться

Объекты редко допускают назначение и другие вещи, например сравнение. Если вы рассмотрите какую-то бизнес-модель с такими объектами, как «Отдел», «Сотрудник», «Директор», трудно представить случай, когда один сотрудник будет назначен другому.

Так что для бизнес-объектов очень хорошо описывать отношения «один-к-одному» и «один-ко-многим» как ссылки, а не указатели.

И, вероятно, нормально описывать отношение «один или ноль» как указатель.

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

Наличие указателя в качестве члена заставит вас или члена вашей команды проверять указатель снова и снова перед использованием, с комментарием «на всякий случай». Если указатель может быть нулевым, то указатель, вероятно, используется как своего рода флаг, что плохо, поскольку каждый объект должен играть свою роль.

33
ответ дан 24 November 2019 в 00:52
поделиться

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

В таких случаях обязательно используйте оператор присваивания (а часто и также конструктор копирования) непригоден для использования (путем наследования от boost :: noncopyable или объявления их закрытыми).

Однако, как уже прокомментировал пользователь pts, это не верно для большинства других объектов. Здесь использование ссылочных элементов может стать огромной проблемой, и его обычно следует избегать.

6
ответ дан 24 November 2019 в 00:52
поделиться

Поскольку все, кажется, раздают общие правила, я предлагаю два:

  • Никогда и никогда не используйте ссылки в качестве членов класса. Я никогда не делал этого в своем собственном коде (кроме как для того, чтобы доказать себе, что я был прав в этом правиле), и не могу представить себе случай, когда я бы сделал это. Семантика слишком запутанная, и на самом деле это не то, для чего были разработаны ссылки.

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

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

6
ответ дан 24 November 2019 в 00:52
поделиться

Да для: Верно ли, что объект, содержащий ссылку, не должен быть назначен, поскольку ссылка не должна изменяться после инициализации?

Мои практические правила для члены данных:

  • никогда не используйте ссылку, потому что это предотвращает присвоение
  • , если ваш класс отвечает за удаление, используйте boost scoped_ptr (который безопаснее auto_ptr)
  • в противном случае используйте указатель или константный указатель
4
ответ дан 24 November 2019 в 00:52
поделиться

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

Да. Читаемость вашего кода. Указатель делает более очевидным, что член является ссылкой (по иронии судьбы :)), а не содержащимся в нем объектом, потому что, когда вы его используете, вы должны отменить ссылку на него. Я знаю, что некоторые люди думают, что это старомодно, но я все же считаю, что это просто предотвращает путаницу и ошибки.

2
ответ дан 24 November 2019 в 00:52
поделиться
Другие вопросы по тегам:

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