Чому C не вважається "об'єктно-орієнтованою" мовою?


92

Здається, що C має свої квазіоб'єкти, такі як "структури", які можна розглядати як об'єкти (так, як ми зазвичай думаємо).

А також, самі файли C - це в основному окремі "модулі", правда? Тоді чи не модулі схожі на "об'єкти"? Мене бентежить питання, чому C, який здається настільки схожим на C ++, вважається "процедурною" мовою низького рівня, де як C ++ є "об'єктно-орієнтованим" високого рівня

* edit: (уточнення) чому і де, намальована лінія, для чого «об’єкт», а ні?


40
Все - чому голоси "за"? Це основне питання, але не погано.
Джон Хопкінс

7
Ви можете ефективно використовувати принципи ОО в C (а люди, які пишуть хороший код C, зазвичай це роблять), але мова не побудована навколо того, щоб зробити це просто, як і багато інших останніх мов.
asveikau

5
C просто має інший, простіший і (якщо чесно) краще визначений (принаймні серед спільноти з відкритим кодом) до абстрагування даних. C ++, як правило, є потужним елементом абстракції і дозволяє зробити багато чудових речей, але коштує зрозуміти, як [не] користуватися ними належним чином, що, як правило, зовсім не вистачає у загальних програмах. Дивіться мою повну відповідь для отримання більш детальної інформації.
Ям Маркович

1
Незабаром: у структур не може бути методів. (Вказівник на функцію не дуже скорочує її).
СФ.

1
Можна об'єктно-програмоване програмування на C, з певними труднощами. Але це не робить його об'єктно орієнтованим .
Клин

Відповіді:


101

Здається, що C має свої квазіоб'єкти, такі як "структури", які можна розглядати як об'єкти

Давайте разом ми з вами прочитаємо сторінку Вікіпедії про об’єктно-орієнтоване програмування та перевіримо особливості структур C-стилю, які відповідають тому, що традиційно вважається об’єктно-орієнтованим стилем:

(OOP) - парадигма програмування, що використовує "об'єкти" - структури даних, що складаються з полів даних та методів разом з їх взаємодіями

Чи складаються структури С із полів та методів разом із їх взаємодіями ? Немає.

Методи програмування можуть включати такі функції, як абстрагування даних, інкапсуляція, обмін повідомленнями, модульність, поліморфізм та успадкування.

Чи C-структури роблять будь-яку з цих речей "першокласним" способом? Ні. Мова працює проти вас на кожному кроці.

об'єктно-орієнтований підхід спонукає програміста розміщувати дані там, де решта програми не доступна безпосередньо

Чи роблять це структури С? Немає.

Об'єктно-орієнтована програма зазвичай містить різні типи об'єктів, кожен тип яких відповідає певному виду складних даних, якими слід керувати, або, можливо, об'єкту чи концепції реального світу

Чи роблять це структури С? Так.

Об'єкти можна розглядати як об'єднання своїх даних у набір функцій, покликаних забезпечити належне використання даних

Немає.

кожен об’єкт здатний приймати повідомлення, обробляти дані та надсилати повідомлення іншим об'єктам

Чи може сама структура надсилати та отримувати повідомлення? Ні. Чи може вона обробляти дані? Немає.

Структури даних OOP, як правило, "несуть із собою власних операторів"

Це трапляється в С? Немає.

Динамічна диспетчеризація ... Інкапсуляція ... Поліморфізм підтипу ... Успадкування об'єктів ... Відкрита рекурсія ... Класи об'єктів ... Екземпляри класів ... Методи, що діють на додані об'єкти ... Проходження повідомлення .. . Абстракція

Чи є якась із цих особливостей структур С? Немає.

Саме які характеристики структур, на вашу думку, є "об'єктно-орієнтованими"? Тому що я не можу знайти який - або інший , ніж той факт , що визначення Структури типу .

Тепер, звичайно, ви можете зробити структури, які мають поля, які є вказівниками на функції. Ви можете зробити, що структури мають поля, які є покажчиками на масиви функціональних покажчиків, відповідні таблицям віртуальних методів. І так далі. Ви, звичайно, можете емулювати C ++ у C. Але це дуже неідіоматичний спосіб програмування на C; вам краще просто використовувати C ++.

А також, самі файли C - це в основному окремі "модулі", правда? Тоді чи не модулі схожі на "об'єкти"?

Знову ж, які характеристики модулів ви думаєте, що змушує їх діяти як об'єкти? Чи підтримують модулі абстракцію, інкапсуляцію, обмін повідомленнями, модульність, поліморфізм та успадкування?

Абстракція та інкапсуляція досить слабкі. Очевидно, що модулі модульні; тому їх називають модулями. Повідомлення? Тільки в тому сенсі, що виклик методу - це повідомлення, і модулі можуть містити методи. Поліморфізм? Ні. Спадщина? Ні. Модулі є досить слабкими кандидатами на «об’єкти».


15
Я не погоджуюся з тим, що "емуляція C ++" (ваш термін) не є ідіоматичною С. Одним із прикладних прикладів може бути те, як ядро ​​ОС зазвичай реалізує файлові операції. Візьмемо Linux як приклад, де у вас є структури, що мають повнофункціональні покажчики. Вони можуть бути дещо "доменними" ідіомами (обмежується написанням драйверів на * nix, скажімо), але вони впізнавані та виконують роботу досить чітко для деяких цілей. Існує також кілька прикладів бібліотек режиму користувача, які досить добре дають поняття OO; візьміть Gtk + і бібліотеки, від яких це залежить. Назвіть це хакі, і ви можете мати рацію, але з цим не страшно працювати
asveikau

5
@asveikau: Чи не означає, що практика є незвичною (навіть якщо не нечуваною) і "хакі" не означає, що вона, за визначенням, не ідіоматична?
Адам Робінсон

19
@asveikau: Впевнені, що ви можете зробити, щоб зробити програми C більш стильними. Але, як ви кажете, для цього потрібна дисципліна; мовні особливості самі по собі не приводять вас до інкапсуляції, поліморфізму, класичного успадкування тощо. Швидше за все, розробник може накласти цю модель на мову. Це не означає, що структури - це логічно те саме, що і об'єкти. Чорт, ви також можете програмувати в стилі ОО в Lisp, але це не означає, що мінуси клітини є об'єктами.
Ерік Ліпперт

3
@asveikau, чи можу я припустити, що ваше (неправильне) тлумачення "ідіоми" як "свого" є м'яко ... ідіосинкратичним? :)
Benjol

8
@BillK: структури не можуть містити код у C. Структури можуть містити функціональні покажчики , які є даними . Покажчики функцій не є кодом . Код - це текстовий артефакт, створений програмістом.
Ерік Ліпперт

46

Ключове слово - «орієнтоване», а не «об’єкт». Навіть код C ++, який використовує об'єкти, але використовує їх як структури, не орієнтований на об'єкти .

І C, і C ++ можуть робити OOP (окрім відсутності контролю доступу в C), але синтаксис робити це в C незручно (якщо не сказати найменше), тоді як синтаксис у C ++ робить його дуже привабливим. C орієнтована на процедурні, тоді як C ++ орієнтована на об'єкти, незважаючи на майже однакові основні можливості в цьому плані.

Код, який використовує об'єкти для реалізації конструкцій, які можна виконати лише з об'єктами (звичайно маючи на увазі переваги поліморфізму), є об'єктно-орієнтованим кодом. Код, який використовує об'єкти трохи менше, ніж пакети даних, навіть використовуючи успадкування мовою, орієнтованою на об'єкти, насправді є просто складним процедурним кодом, ніж це має бути. Код в C, який використовує функціональні покажчики, які змінюються під час виконання зі структурами, повними даними, начебто роблять поліморфізм, і, можна сказати, "об'єктно-орієнтований", навіть на процедурно орієнтованій мові.


2
+1 Для вказівки наш C може бути ОО. Це не зручно, але це можна зробити.
дієтабудда

Створювати об’єкти в VBA простіше, але я б і не вважав це об'єктом "орієнтованим".
JeffO

VBA Я називаю "об'єкт на основі". Він використовує об'єкти, але не поліморфно, і в цій роботі, яку я зробив над цим, я не впевнений, що ви навіть можете зробити поліморфізм, незалежно від того, який тип акробатики коду ви намагаєтеся. Це в основному процедурна мова з інкапсуляцією.
kylben

2
Більшість мов можуть діяти як ОО, функціональні або майже будь-який стиль мови. Різниця полягає в "Орієнтованому", і я ніколи не чув, щоб це було так раніше. Я хотів би, щоб я міг проголосувати за це 3 рази і прийняти це, це правильна відповідь.
Білл К

1
@kylben Це не було б великим розтягненням, щоб зберігати SQL-код у таблиці, потім витягувати та виконувати (роблячи таблицю вашим об'єктом). Це був би цікавий експеримент. Насправді це трохи спокусливо ...
Білл К

19

На основі принципів найвищого рівня:

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

Структури містять дані, але не мають поведінки, і тому їх не можна вважати об'єктами.

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

І це перш ніж потрапити на спадщину та поліморфізм ...


Як поведінка та дані в модулях не пов’язані між собою? Чи не є членами функції в основному "поведінка" даних, які існують всередині модуля?
Темний тамплієр

4
Проблема в тому, що вони не капсульовані, не в тому, що вони не пов'язані між собою.
Еойн Керролл

Насправді об'єкти орієнтовані головним чином на поведінку , а не на дані. Дані є / повинні бути громадянами другого класу в ООП. Натомість структури зосереджені навколо даних і не мають поведінки.
Sklivvz

1
@Dark Templar - Що сказав Еойн ... Це в характері стосунків. Я бачу, звідки ви беретеся - ви, звичайно, можете використовувати Structs в модулі таким чином, що він імітував деякі дуже основні елементи OO, але багато з того, що ви робите, буде покладатися на програміста, який дотримується набору правил, які самостійно накладають, а не того, щоб мова їх застосовувала. І навіщо ти турбуєшся? Ви не отримуєте жодної переваги OO - немає спадщини, наприклад, - і обмежуєте себе.
Джон Хопкінс

Це краща відповідь, ніж правильна.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

6

"структури" - це лише дані. Звичайний швидкий і брудний тест на "орієнтацію на об'єкт": "Чи існує структура, яка дозволяє коду і даних інкапсулювати як єдину одиницю?". C цього не дає, а значить, є процедурною. C ++ проходить цей тест.


6
Існують обхідні шляхи, структури можуть мати статичні покажчики функцій на функції членів. На них знадобиться чіткий thisпокажчик, але в цьому випадку дані та засоби для обробки даних будуть інкапсульовані всередині структури.
Кодер

@Brian Knoblauch: але чи не є самим файлом C інкапсуляція даних та коду ??
Темний тамплієр

@DarkTemplar У певному сенсі, так, але якщо вам не вдасться створити одиниці перекладу, компілювати їх і завантажувати їх у запущений процес під час виконання, це мало користі.

перекладацькі одиниці? >. <
Темний тамплієр

@Dark Templar: Блок перекладу - це вихідний файл плюс усе, що #includeв ньому, і мінус усе, що видаляється, якщо його умовно не включати ( #if, #ifdefтощо).
Девід Торнлі

5

C, як і C ++, має можливість надання Абстракції даних , що є однією ідіомою об'єктно-орієнтованої програмувальної парадигми, що існувала до неї.

  • C структури можуть мати дані (і це їх головне призначення)
  • С-структури також можуть визначати покажчики функцій як дані
  • C структури можуть і часто мають набір функцій, пов'язаних з ними, подібно до методів, лише цей покажчик не передається неявно, але ви повинні вказати його явно як перший аргумент до кожного методу, призначеного для обробки зазначеної структури. C ++ робить це автоматично для вас, як при визначенні, так і при виклику методів класу / структури.

OOP в C ++ поширює засоби на абстрактні дані. Одні кажуть, що це шкідливо , а інші вважають це хорошим інструментом при правильному використанні.

  • C ++ робить цей покажчик неявним, не вимагаючи від користувача передавати його в "методи класу / структури" до тих пір, поки тип може бути (принаймні частково) ідентифікований.
  • C ++ дозволяє обмежити доступ до певних методів (функцій класу), а отже, дозволяє отримати більше "оборонного програмування" або "ідіотії".
  • C ++ заохочує абстрагування, забезпечуючи більш високу безпеку типу шляхом впровадження
    1. Новий оператор замість Таноса + гіпс
    2. Шаблони замість недійсних покажчиків
    3. Вбудовані функції, які отримують набрані значення замість макросів
    4. Вбудований в поліморфізм, який вам не доведеться реалізовувати самостійно, що дозволяє створювати ієрархії абстракцій , контракти та спеціалізації .

Однак ви знайдете безліч С "хакерів", які проповідують про те, наскільки C цілком здатний надати потрібну кількість абстракцій і як накладні витрати, створені C ++, лише відволікають їх від вирішення фактичної проблеми.

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

Інші схильні дивитися на це більш врівноважено, приймаючи як переваги, так і недоліки.

C дозволяє легко стріляти собі в ногу; C ++ робить це важче, але коли ви це робите, це відбиває всю ногу. - Bjarne Stroustrup


2

Потрібно подивитися на інший бік монети: C ++.

В OOP ми думаємо про абстрактний об'єкт (і відповідно розробити програму), наприклад автомобіль, який може зупинятися, розганятися, повертати ліворуч або праворуч тощо. Структура з набором функцій просто не відповідає концепції.

З "реальними" об'єктами нам потрібно приховати членів, наприклад, або ми також можемо мати спадщину з реальними "відносинами" та багато іншого.

ПІСЛЯ ЧИТАННЯ ВІДКЛЮЧЕНИХ КОМЕНТАРІВ: Добре, що (майже) все можна зробити за допомогою C (це завжди правда), але на перший погляд я подумав, що те, що відокремлює c від c ++, - це те, як ви думаєте при розробці програми.

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


Не дуже впевнений, чому структура з "пакетом функцій" не відповідає концепції? +1 для відповіді, хоча
Темний тамплієр

1
Крім контролю доступу (приватного / захищеного / загальнодоступного), все інше можна зробити за допомогою структур.
Кодер

1
@DarkTemplar: Ну, ви можете спробувати наслідувати OOP в C (люди насправді писали електронні книги на цю тему і роблять це в реальному світі, хоча і дуже рідко), як ви можете спробувати емуляцію функціонального програмування на Java. Але C надає нульову допомогу для цього, отже, мова C не орієнтована на об'єкти .

1

Ви свого роду це сказали самі. Хоча в C є речі, схожі на об'єкти, вони все ще не є об'єктами, і тому C не вважається мовою ООП.


1
Ну, напевно, питання: чому і де намальована лінія для того, що є об'єктом, а що ні?
Темний тамплієр

1

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

Ви можете реалізувати "OO" дизайн (робочий стіл Gnome - це, мабуть, найкращий приклад OO, виконаний у чистому С), я навіть бачив, що це робиться з COBOL!

Однак, будучи спроможним реалізувати проектну дозу OO, не перекладайте мову OO. Пуристи стверджують, що Java і C ++ справді не є OO, оскільки ви не можете переосмислити або успадкувати основні "типи", такі як "int" і "char", а Java не підтримує багаторазове успадкування. Але оскільки вони є найбільш широко використовуваними мовами OO і підтримують більшість парадигми, більшість "справжніх" програмістів, які платять за створення робочого коду, розглядають їх як мови ОО.

З іншого боку, C підтримує лише структури (як COBOL, Pascal та десятки інших процедурних мов), ви можете стверджувати, що підтримує багатократне успадкування, оскільки ви можете використовувати будь-яку функцію на будь-якій частині даних, але більшість вважає це помилкою ніж особливість.


0

Давайте просто розглянемо визначення ОО:

  • Повідомлення
  • Інкапсуляція
  • Пізнє зв’язування

C не забезпечує жодного з цих трьох. Зокрема, він не забезпечує обмін повідомленнями , що є найважливішим.


1
Я думаю, я мав би не погодитися з цим. Ви, звичайно, можете мати обмін повідомленнями в C - працювати з API C Об'єктивних програм від C, і ви дізнаєтесь, що це поглиблено - і пізнє зв'язування можна зробити за допомогою функціональних покажчиків, але ви не отримаєте багато синтаксичного цукру, щоб приховати це. (Інкапсуляція насправді проста на C; вказівники на неповні типи структур роблять цю роботу ідеально.)
Donal Fellows

Спадщина також вважається важливим в ОО, і C не робить цього. Найближче до інкапсуляції в C - це окремі файли, які можуть мати внутрішні ( static) функції та члени даних.
Девід Торнлі

@DonalFellows, фактичне передача повідомлення в Objective-C може бути легко реалізована як макрос C99. Єдине, на що збирається компілятор, це те, що він генерує всі необхідні структури статично з кількох рядків коду високого рівня. Більшість, якщо не всі функції доступні з API API.
qpr

0

Існує ряд ключових інгредієнтів для OO, але великими є те, що більшість кодів не знає, що знаходиться всередині об'єкта (вони бачать поверхневий інтерфейс, а не реалізацію), що стан об'єкта є керованою одиницею (тобто коли об'єкт перестає бути таким, як і його стан), і коли якийсь код викликає операцію на об'єкті, вони роблять це, не знаючи, що саме ця операція є чи пов'язана з цим (все, що вони роблять, - це слідувати шаблону, щоб кинути кидок "Повідомлення" над стіною).

C робить інкапсуляцію просто чудовою; код, який не бачить визначення структури, не може (законно) зазирнути всередину неї. Все, що вам потрібно зробити, - це поставити таке визначення у файл заголовка:

struct FooImpl;
typedef struct FooImpl *Foo;

Звичайно, виникне потреба у функції, яка будує Foos (тобто фабрику), і яка повинна делегувати частину роботи самому виділеному об'єкту (тобто методом "конструктор"), а також мати спосіб утилізації об'єкта ще раз (дозволяючи прибирати його методом «деструктор»), але це деталі.

Відправлення методу (тобто обміну повідомленнями) також може бути здійснено через умову про те, що перший елемент структури є фактично вказівником на структуру, повну функціональних покажчиків, і що кожен із цих покажчиків функцій повинен брати Fooсвій перший аргумент. Потім відправка стає предметом пошуку функції та виклику її за допомогою правильного перезапису аргументу, що не так важко зробити з макросом і трохи хитро. (Ця таблиця функцій є ядром того, що клас насправді є такою мовою, як C ++.)

Крім того, це дає і пізнє прив'язування: все, що диспетчерський код знає, це те, що він викликає певний зсув у таблицю, на яку вказує об'єкт. Це потрібно встановити лише під час розподілу та ініціалізації об'єкта. Можна скористатися ще складнішими схемами диспетчеризації, які купують вам більше динамічності виконання (ціною швидкості), але вони вишні поверх основного механізму.

Але це не означає, що C є мовою ОО. Ключовим моментом є те, що C залишає вас робити всю складну роботу над написанням конвенцій та механізмом відправки самостійно (або використовувати сторонні бібліотеки). Це багато роботи. Він також не забезпечує синтаксичну або семантичну підтримку, тому впровадження повноцінної системи класів (з такими речами, як спадкування) було б зайвим болючим; якщо ви маєте справу зі складною проблемою, яка добре описана моделлю ОО, мова ОО буде дуже корисною при написанні рішення. Додаткову складність можна виправдати.


0

Я думаю, що C ідеально чудовий і пристойний для реалізації об'єктно-орієнтованих концепцій, знизайте плечима . Я вважаю, що більшість відмінностей між загальним набором знаменника мов, що вважаються об'єктно-орієнтованими, є мінорними та синтаксичними за своєю суттю з мого прагматичного погляду.

Почнемо з, скажімо, приховування інформації. У C ми можемо досягти цього, просто приховавши визначення структури та працюючи з нею через непрозорі покажчики. Це ефективно моделює publicпорівняно з privateвідмінністю полів даних, як ми отримуємо з класами. І це досить легко зробити і навряд чи є антиідіоматичним, оскільки стандартна бібліотека С дуже покладається на це, щоб досягти приховування інформації.

Звичайно, ви втрачаєте здатність легко керувати саме тим місцем, де структура виділена в пам'яті, використовуючи непрозорі типи, але це лише примітна різниця між, скажімо, C і C ++. C ++, безумовно, є чудовим інструментом при порівнянні його здатності програмувати об'єктно-орієнтовані концепції на C, зберігаючи при цьому контроль над макетами пам'яті, але це не обов'язково означає, що Java або C # переважають над C у цьому плані, оскільки ці два змушують вас повністю втрачають здатність контролювати, де об’єкти виділяються в пам'яті.

І ми мусимо використовувати синтаксис, як fopen(file, ...); fclose(file);на відміну від, file.open(...); file.close();але великий whoop. Кого насправді хвилює? Можливо, просто хтось, хто сильно схиляється до автозаповнення в IDE. Я визнаю, що це може бути дуже корисною з практичної точки зору, але, можливо, не такою, яка потребує обговорення того, чи підходить мова для ООП.

Нам не вистачає здатності ефективно реалізовувати protectedполя. Я повністю підпорядкуюсь там. Але я не думаю, що існує конкретне правило, яке говорить: " Усі мови OO повинні мати функцію, яка дозволяє підкласам отримувати доступ до членів базового класу, до яких звичайний клієнт не має доступу ". Крім того, я рідко бачу випадки використання для захищених членів, які хоча б трохи не підозріло стають перешкодою для обслуговування.

І звичайно, ми мусимо "наслідувати" поліморфізм ОО за допомогою таблиць функціональних покажчиків та покажчиків на них для динамічної відправки з трохи більше котлової панелі, щоб ініціалізувати ці аналогічні vtablesта vptrs, але трішки котельні ніколи не завдавали мені великого горя.

Спадкування майже однаково. Ми можемо легко моделювати, що за складом і при внутрішній роботі компіляторів це зводиться до того ж самого. Звичайно, ми втрачаємо безпеку типу, якщо ми хочемо знизити збиток , і там я б сказав, якщо ви взагалі хочете бути зривкою , щоб не використовувати для цього C, оскільки те, що люди роблять в C для емуляції спаду, може бути жахливим від типу точки зору безпеки, але я вважаю за краще, щоб люди взагалі не пригнічувались . Безпека типу - це те, що ви можете легко пропустити в C, оскільки компілятор забезпечує стільки свободи інтерпретації речей як просто біти та байти, жертвуючи здатністю ловити потенційні помилки під час компіляції, але деякі мови вважаються об'єктно-орієнтованою ареною навіть не статично набраний.

Так не знаю, я думаю, що це добре. Звичайно, я б не використовував C, щоб намагатися створити масштабну кодову базу, яка відповідає принципам SOLID, але це не обов'язково через його коротких заїздів на об'єктно-орієнтований фронт. Багато можливостей, які я б пропустив, якби я спробував використовувати C для такої мети, був би пов'язаний з мовними особливостями, які безпосередньо не вважаються необхідною умовою OOP, наприклад, безпека сильного типу, деструктори, які автоматично викликаються, коли об'єкти виходять із сфери дії, оператор перевантаження, шаблони / дженерики та обробка виключень. Коли мені не вистачає тих допоміжних функцій, до яких я досягаю C ++.


1
Я не впевнений, як конструктори не можна вважати передумовою OOP. Частиною основної сутності інкапсуляції є здатність забезпечити інваріанти для об'єкта. А для цього потрібна можливість належної ініціалізації об'єкта в межах цих інваріантів. Для цього потрібен конструктор: одна або кілька функцій, так що ви не можете сказати, що об'єкт існує ще до того часу, поки не буде викликана хоча б одна з них.
Ніколь Болас

Коли у нас є інформація, що приховується з непрозорими типами, то єдиний спосіб їх копіювання та копіювання / клонування та знищення - це через аналогічний еквівалент функцій, що виконують функції конструкторів та деструкторів з такою ж здатністю підтримувати ці інваріанти. Це просто не безпосередньо моделюються на мову і може нагадувати форму foo_createі foo_destroyта foo_clone, наприклад

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

Так, я знаю, як люди впроваджують OOP в C, дякую. Моя думка полягала в тому, що ваше твердження про те, що конструктори "не вважаються безпосередньо умовою OOP", є помилковим.
Нікол Болас

Я бачу, лемма це виправдає ... але в такому випадку ми можемо сказати, що C забезпечує (адекватну?) Підтримку деструкторів та конструкторів?

-1

Непогане питання.

Якщо ви збираєтесь називати c мовою ОО, вам потрібно буде подзвонити майже про всі процедурні мови OO. Тож це зробило б термін безглуздим. c не має мовної підтримки для ОО. Якщо має структури, але структури - це typesне класи.

Насправді у c зовсім не багато функцій порівняно з більшістю мов. Це в основному використання для його швидкості, простоти, популярності та підтримки, включаючи багато бібліотек.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.