Функция-член против функции не-члена? - PullRequest
8 голосов
/ 04 апреля 2009

Каково ваше правило, для которого функции, которые работают с классом, должны быть функциями-членами, а не функциями, не являющимися членами? Например, у меня есть класс, который представляет лабиринт с использованием матрицы bools. Я делаю функцию с именем isConnected, которая проверяет, что 2 точки в лабиринте находятся в одной и той же области (то есть можно перемещаться из А в В).

Должно ли это быть членом или не членом? Что такое хорошее правило?

Ответы [ 6 ]

14 голосов
/ 04 апреля 2009

Херб Саттер говорит: «Мы хотим, чтобы они не были друзьями, если это возможно», и он умнее меня.

http://www.gotw.ca/gotw/084.htm

13 голосов
/ 04 апреля 2009

Ну, есть аргументы для обоих.

В пользу функций, не являющихся членами:

  • предлагает лучшую инкапсуляцию
  • Это позволяет лучше повторно использовать код (std :: find может быть повторно использован для любого типа контейнера, потому что это бесплатная функция. Если бы он был членом, когда-либо контейнер должен был бы определять свой собственный)
  • Это упрощает многие общие приемы программирования. (container.begin() недопустим, если container является массивом. Это делает его более неудобным для написания универсального кода, работающего с контейнерами. Но begin(container) можно сделать допустимым для любого типа, даже встроенного, такого как массивы) , Это также может сделать миксины с помощью композиции намного чище, потому что не требуется, чтобы пользователь «расставлял точки» через членов, чтобы добраться до объекта миксина, с которым вы хотите работать.

В пользу создания функций-членов является:

  • Это знакомо. Java и C # требуют этого, и, по мнению многих программистов, функции-члены являются синонимами ООП.

и ... вот и все. (Но этот аргумент не следует недооценивать. Читаемость кода важна, и если людям легче читать версию участника, это сильный аргумент в ее пользу. Он просто не дает лучшего кода. Из строгого «лучшего кода» с точки зрения, не члены должны быть предпочтительнее, когда это возможно.

11 голосов
/ 04 апреля 2009

Когда сделать функцию-член:

  • когда функция логически связана с классом (как ваш пример подключения лабиринта)
  • когда функции нужен доступ к закрытым или защищенным членам, лучше сделать ее участником, чем другом.

Когда сделать его автономной функцией

  • когда это универсальная функция, которую можно шаблонизировать для естественной работы с другими классами (хороший пример приведен в заголовке )
4 голосов
/ 04 апреля 2009

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

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

3 голосов
/ 04 апреля 2009

Я всегда возвращаюсь к FAQ 13.9 . Это не точная наука, а основанная на усмотрении.

Упрощенно говорить, что всякий раз, когда вам нужен доступ к внутренним элементам класса, вы должны использовать члена. Примечательными примерами являются операторы вставки / извлечения потока (>> и << соответственно) и двоичный файл +.

В вашем примере isConnected - это метод для проверки состояния объекта, то есть инспектора и идеального кандидата на членство.

0 голосов
/ 04 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...