Де в об'єктно-орієнтованій системі вам слід, якщо взагалі, вибирати (C-стиль) структури над класами?


9

C і, швидше за все, багато інших мов надають structключове слово для створення структур (або щось подібне). Це (принаймні в С), з спрощеної точки зору, як класи, але без поліморфізму, успадкування, методів тощо.

Подумайте про об'єктно-орієнтовану (або мульти-парадигму) мову зі структурами у стилі С. Де ви б обрали їх на заняттях? Тепер я не вірю, що вони повинні використовуватися з OOP, оскільки класи, здається, замінюють свої цілі, але мені цікаво, чи існують ситуації, коли їх можна віддати перевагу класам в інших об'єктно-орієнтованих програмах та в яких ситуаціях. Чи бувають такі ситуації?


Якою мовою ви користуєтесь? Що ви публікуєте? Більшість сучасних мов OO, за винятком Java, так чи інакше підтримують властивості.
кевін клайн

Відповіді:


16

У деяких книгах я бачив різницю між об'єктами, що несуть стан, і об'єктами, що надають функціональність. Точні умови відрізняються від джерела до джерела. Але загалом кажучи, перші відрізняються тим, що мають купу полів і цілу купу простих пар геттерів-сеттерів (а може бути і конструктор).

Вони особливо поширені на Java для класів, які явно позначені як "серіалізаційні".

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


1
Роберт C Мартін називає їх «об'єкти передачі даних» в чистому кодексі .
user16764

5

У C класів немає, тому structє спосіб згрупування даних. У C ++ - structце те саме, що, classза винятком того, що спадкування та доступ членів publicза замовчуванням, а не private. C # також має щось на зразок struct, але я не знаю достатньо C #, щоб прокоментувати це. Звичайний Lisp має defstructформу, яка працює настільки ж, наскільки C structs, з огляду на мовну різницю, і відрізняється від класу Common Lisp Object System System.

Однак існує концептуальна різниця між пов'язаним пакетом даних та реальним класом, а в C ++ structчасто використовується для набору даних, тоді classяк використовується для об'єктів, які повинні мати власну поведінку. В якості керівництва я б сказав, що a classявляє собою те, про що ви можете сказати щось корисне, наприклад, інваріант класу, тоді як a structбуло б більш вільно поєднане зі значеннями даних, не дуже залежними від інших.


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

0

На самому базовому рівні, в чому різниця між структурою та чистим класом даних (той, який не має функціоналу, окрім аксесуарів власності)?

Насправді нічого, крім сліду пам’яті.


0

Прийнята відповідь хороша. Я просто хотів би додати….

Іноді краще покласти метод всередину класу. В інших випадках краще мати зовнішню функцію, коли структура / клас передається як параметр (навіть якщо ви використовуєте стиль OOP).

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

приклад того, коли поставити функцію поза класом: Canvas.Draw (прямокутник прямої)

ви можете помістити Draw () всередину Прямокутника, і він спрацює. Але малювання - це операція, що залежить від рівня. Ви б малювали не на стороні сервера, а на стороні клієнта. Draw () не мало б сенсу навіть існувати на сервері. Однак "CalculateArea ()" не залежить від рівня і є справжнім атрибутом прямокутника, тому краще включити його як метод-член.


0

Для мене велика різниця в тому, є клас-інваріант чи ні.

Або іншими словами: я вільний змінити будь-яке поле на будь-яке значення в будь-який момент часу? Якщо так, це структура; Якщо ні, то це клас.

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

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


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.