Где, в объектно-ориентированной системе, следует ли вообще выбирать (в стиле C) структуры над классами?


9

C и, скорее всего, многие другие языки предоставляют structключевое слово для создания структур (или чего-то подобного). Это (по крайней мере, в C), с упрощенной точки зрения, как классы, но без полиморфизма, наследования, методов и так далее.

Подумайте об объектно-ориентированном (или мульти-парадигмальном) языке со структурами в стиле C. Где бы вы выбрали их по классам? Теперь я не верю, что они должны использоваться с ООП, поскольку классы, кажется, заменяют их цели, но мне интересно, есть ли ситуации, когда они могут быть предпочтительнее классов в других объектно-ориентированных программах и в каких ситуациях. Есть ли такие ситуации?


Какой язык вы используете? Что вы публикуете? Большинство современных ОО-языков, кроме Java, так или иначе поддерживают свойства.
Кевин Клайн

Ответы:


16

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

Они особенно распространены в Java для классов, которые явно помечены как «сериализуемые».

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


1
Роберт С. Мартин называет их «объектами передачи данных» в « Чистом коде» .
user16764

5

В C нет классов, поэтому structесть способ связать данные. В C ++ structэто то же самое, classза исключением того, что наследование и доступ publicк элементам по умолчанию, а не private. C # также имеет своего рода struct, но я не знаю достаточно C #, чтобы комментировать. Common Lisp имеет defstructформу, которая работает как C, structнасколько это возможно, учитывая разницу в языке, и отличается от класса Common Lisp Object System.

Однако существует концептуальное различие между связанным пакетом данных и реальным классом, и в C ++ structчасто используется для пакета данных, в то время classкак используется для объектов, которые должны иметь свое собственное поведение. В качестве руководства я бы сказал, что a classпредставляет собой нечто , о чем вы можете сказать что-то полезное, например, инвариант класса, тогда как a structбудет более свободно связано со значениями данных, которые в действительности не сильно зависят от других.


6
Разница между a structи a classболее значительна в C # - главное, что a structявляется типом значения, а a classявляется ссылочным типом. Microsoft рекомендует не использовать, structесли содержимое будет больше 16 байт или около того.
Carson63000

0

На самом базовом уровне, в чем разница между структурой и классом чистых данных (который не имеет никакой функциональности, кроме средств доступа к свойствам)?

Ничего, кроме следа памяти на самом деле.


0

Принятый ответ хорош. Я просто хотел бы добавить ....

Иногда лучше поместить метод в класс. В других случаях лучше иметь внешнюю функцию, в которой структура / класс передается в качестве параметра (даже если вы используете стиль ООП).

Пример того, когда нужно поместить метод внутри класса: Rectangle.CaclulateArea ()

Пример того, когда нужно поместить функцию вне класса: Canvas.Draw (Rectangle rect)

Вы можете поместить Draw () внутри прямоугольника, и это будет работать. Но рисование зависит от уровня. Вы бы рисовали не на стороне сервера, а на стороне клиента. Draw () не имеет смысла даже существовать на сервере. Однако «CalculateArea ()» не зависит от уровня и является истинным атрибутом прямоугольника, поэтому лучше включить его в качестве метода-члена.


0

Для меня большая разница в том, существует ли класс-инвариант или нет.

Или другими словами: могу ли я изменить любое поле на любое значение в любой момент времени? Если это так, это структура; Если нет, то это класс.

Обычным примером структуры является 2D-точка, содержащая только элементы X и Y, которые могут иметь любое значение и полностью независимы друг от друга. Публичный доступ приемлем.

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


0

1) Сеть structs: структуры, которые передаются по проводам.

В более общем и формальном смысле, любой класс, который вам требуется, должен быть POD, тривиальным, стандартным макетом или связанной концепцией. Для превосходного обсуждения этих концепций, с примерами, посмотрите этот ответ (это для C ++ 11).

2) Функторы (в частности, предикаты), которые вы передаете таким функциям, как std::remove_if. Иначе говоря, классы похожи на / унаследованы std::binary_functionили тому подобное.

3) Концепции метапрограммирования, которые могут содержать только публичные constexprs и / или typedefs.

Изменить: Примечание: этот ответ относится к классам C ++ против структур.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.