Почему C не считается «объектно-ориентированным» языком?


92

Кажется, что у С есть свои квазиобъекты, такие как «структуры», которые можно рассматривать как объекты (на высоком уровне, который мы обычно думаем).

Кроме того, сами файлы C в основном являются отдельными "модулями", верно? Тогда разве модули тоже не похожи на «объекты»? Меня смущает, почему C, который кажется очень похожим на C ++, считается низкоуровневым "процедурным" языком, где C ++ является высокоуровневым "объектно-ориентированным"

* edit: (уточнение) почему и где проводится линия, для чего это «объект», а что нет?


40
Все - почему проголосовали за? Это основной вопрос, но не плохой.
Джон Хопкинс

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

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

1
Коротко: Структуры не могут иметь методы. (Указатель на функцию не совсем обрезает ее).
SF.

1
Можно сделать объектно-ориентированное программирование на C, с некоторыми трудностями. Но это не делает его объектно- ориентированным .
Клин

Ответы:


101

Кажется, что у C есть свои квазиобъекты, такие как «структуры», которые можно рассматривать как объекты

Давайте вместе рассмотрим страницу Википедии об объектно-ориентированном программировании и отметим особенности структур в стиле C, которые соответствуют тому, что традиционно считается объектно-ориентированным стилем:

(ООП) - это парадигма программирования, использующая «объекты» - структуры данных, состоящие из полей данных и методов вместе с их взаимодействиями.

Структуры C состоят из полей и методов вместе с их взаимодействиями ? Нет .

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

Структуры C выполняют какие-либо из этих вещей "первоклассным" способом? Нет. Язык работает против вас на каждом шагу.

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

Структуры C делают это? Нет.

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

Структуры C делают это? Да.

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

Нет.

каждый объект способен принимать сообщения, обрабатывать данные и отправлять сообщения другим объектам

Может ли сама структура отправлять и получать сообщения? Может ли он обрабатывать данные? Нет.

ООП структуры данных, как правило, «несут с собой своих собственных операторов»

Это происходит в C? Нет.

Динамическая диспетчеризация ... Инкапсуляция ... Полиморфизм подтипов ... Наследование объектов ... Открытая рекурсия ... Классы объектов ... Экземпляры классов ... Методы, которые воздействуют на присоединенные объекты ... Передача сообщений .. Абстракция

Есть ли какие-либо из этих особенностей структур C? Нет.

Какие именно характеристики структур, по вашему мнению, являются «объектно-ориентированными»? Потому что я не могу найти ничего, кроме факта, что структуры определяют типы .

Теперь, конечно, вы можете создавать структуры, которые имеют поля, которые являются указателями на функции. Вы можете сделать структуры иметь поля, которые являются указателями на массивы указателей на функции, соответствующие таблицам виртуальных методов. И так далее. Конечно, вы можете эмулировать C ++ на C. Но это очень не идиоматический способ программирования на C; вам лучше использовать C ++.

Кроме того, сами файлы C в основном являются отдельными "модулями", верно? Тогда разве модули тоже не похожи на «объекты»?

Опять же, о каких характеристиках модулей вы думаете, что заставляет их действовать как объекты? Поддерживают ли модули абстракцию, инкапсуляцию, обмен сообщениями, модульность, полиморфизм и наследование?

Абстракция и инкапсуляция довольно слабы. Очевидно, что модули являются модульными; Вот почему они называются модулями. Сообщения? Только в том смысле, что вызов метода является сообщением, а модули могут содержать методы. Полиморфизм? Нет. Наследование? Нет. Модули являются довольно слабыми кандидатами на «объекты».


15
Я не согласен с тем, что «эмуляция C ++» (ваш термин) не является идиоматическим C. Одним из встречных примеров будет то, как ядро ​​ОС обычно реализует файловые операции - возьмем Linux в качестве примера, где у вас есть структуры, полные указателей на функции. Они могут быть в некоторой степени «предметно-специфическими» идиомами (скажем, ограничены написанием драйверов для * nix), но они распознаваемы и выполняют работу достаточно чисто для некоторых целей. Есть также несколько примеров библиотек пользовательского режима, которые достаточно хорошо понимают ОО; возьмите Gtk + и библиотеки, от которых это зависит. Назовите это хакерским, и вы можете быть правы, но с этим не страшно работать
asveikau

5
@asveikau: Разве идея о том, что практика необычна (даже если не неслыханна) и "хакерская", означает, что она по определению не идиоматична?
Адам Робинсон

19
@asveikau: Конечно, есть вещи, которые вы можете сделать, чтобы сделать программы на С более стильными. Но, как вы говорите, для этого требуется дисциплина; Сами языковые функции не ведут вас к инкапсуляции, полиморфизму, наследованию классов и так далее. Скорее разработчик может навязать этот шаблон на язык. Это не значит, что структуры логически совпадают с объектами. Черт возьми, вы также можете программировать в ОО-стиле на Лиспе, но это не значит, что клетки-противники являются объектами.
Эрик Липперт

3
@asveikau, могу ли я предположить, что ваше (неправильное) толкование «идиомы» как «своего» мягко ... своеобразно? :)
Бенджол

8
@BillK: Структуры не могут содержать код на C. Структуры могут содержать указатели на функции , которые являются данными . Указатели на функции не являются кодом . Код - это текстовый артефакт, созданный программистом.
Эрик Липперт

46

Ключевое слово «ориентированный», а не «объект». Даже код C ++, который использует объекты, но использует их как структуры, не является объектно- ориентированным .

C и C ++ могут одновременно выполнять ООП (кроме контроля доступа в C), но синтаксис для этого в C неудобен (если не сказать больше), в то время как синтаксис в C ++ делает его очень привлекательным. C ориентирован на процедурный, в то время как C ++ ориентирован на объекты, несмотря на почти идентичные основные возможности в этом отношении.

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


2
+1 За указание нашего С может быть ОО. Это не удобно, но это можно сделать.
dietbuddha

Создавать объекты в VBA проще, но я бы тоже не считал их объектно-ориентированными.
JeffO

VBA я называю «объектным». Он использует объекты, но не полиморфно, и из-за небольшой работы, которую я проделал, я не уверен, что вы даже можете сделать полиморфизм, независимо от того, какой тип акробатики кода вы пробуете. Это в основном процедурный язык с инкапсуляцией.
kylben

2
Большинство языков может выступать в качестве ОО, функционального или почти любого стиля языка. разница в «ориентированности», и я никогда не слышал, чтобы это было так. Я хотел бы проголосовать за это 3 раза и принять это, это правильный ответ.
Билл К

1
@kylben Было бы не слишком сложно сохранить SQL-код в таблице, а затем извлечь и выполнить его (сделав таблицу вашим объектом). Это был бы интересный эксперимент. На самом деле это немного заманчиво ...
Билл К

19

Основано на принципах самого высокого уровня:

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

Структуры содержат данные, но не имеют поведения и поэтому не могут рассматриваться как объекты.

Модули содержат как поведение, так и данные, но не инкапсулированы таким образом, что эти два связаны и, конечно, не могут быть созданы несколько раз.

И это прежде, чем вы перейдете к наследованию и полиморфизму ...


Почему поведение и данные в модулях не связаны? Разве функции-члены не являются в основном «поведением» данных, которые существуют внутри модуля?
Темный тамплиер

4
Проблема в том, что они не инкапсулированы, а не в том, что они не связаны.
Эоин Кэрролл

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

1
@ Темный тамплиер - То, что сказала Эоин ... Это в природе отношений. Я вижу, откуда вы идете - вы, безусловно, могли бы использовать Structs внутри модуля таким образом, чтобы он эмулировал некоторые очень элементарные элементы ОО, но многое из того, что вы бы делали, зависело от программиста, придерживающегося набора добровольных правил, а не того, чтобы язык приводил их в исполнение. И зачем тебе это? Вы не получаете ни одного из преимуществ ОО - например, никакого наследования - и вы ограничиваете себя.
Джон Хопкинс

Это лучший ответ, чем тот, который помечен как правильный.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

6

«структуры» являются только данными. Обычный быстрый и грязный тест «объектной ориентации» таков: «Существует ли структура, позволяющая инкапсулировать код и данные как единое целое?». С не удается, и, следовательно, является процедурным. C ++ проходит этот тест.


6
Есть обходные пути, структуры могут иметь статические указатели на функции-члены. Им понадобится явный thisуказатель, но в этом случае данные и средства для обработки данных будут инкапсулированы внутри структуры.
Кодер

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

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

единицы перевода? >. <
Темный тамплиер

@Dark Templar: Блок перевода исходного файла плюс что - #included в него, и минус что - то удалены не условно включены ( #if, #ifdefи тому подобное).
Дэвид Торнли

5

C, как и C ++, обладает способностью предоставлять Data Abstraction , которая является одной из идиом парадигмы объектно-ориентированного программирования, существовавшей до него.

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

ООП в C ++ расширяет средства для абстрагирования данных. Некоторые говорят, что это вредно , в то время как другие считают это хорошим инструментом при правильном использовании.

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

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

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

Другие склонны смотреть на это более взвешенно, принимая как преимущества, так и недостатки.

С позволяет легко выстрелить себе в ногу; С ++ делает это сложнее, но когда вы это делаете, это отрывает вам ногу. - Бьярне Страуструп


2

Вам нужно взглянуть на другую сторону медали: C ++.

В ООП мы думаем об абстрактном объекте (и проектируем программу соответственно), например, автомобиль, который может останавливаться, ускоряться, поворачивать влево или вправо и т. Д. Структура с набором функций просто не соответствует концепции.

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

ПОСЛЕ ПРОЧИТАНИЯ КОММЕНТАРИЙ НИЖЕ: Хорошо, что (почти) все можно сделать с C (это всегда так), но на первый взгляд я подумал, что то, что отличает c от c ++, - это то, что вы думаете при разработке программы.

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


Не совсем уверен, почему структура с «набором функций» не соответствует концепции? +1 за ответ, хотя
Темный тамплиер

1
Помимо контроля доступа (частный / защищенный / общедоступный) все остальное можно сделать с помощью структур.
Кодер

1
@DarkTemplar: Ну, вы можете попытаться эмулировать ООП в C (люди действительно пишут книги на эту тему и делают это в реальном мире, хотя и очень редко), как вы можете попробовать эмулировать функциональное программирование в Java. Но C не дает никакой помощи, поэтому язык C не является объектно- ориентированным .

1

Вы вроде сказали это сами. Хотя в C есть вещи, которые похожи на объекты, они все же не являются объектами, и поэтому C не считается языком ООП.


1
Ну, я думаю, вопрос в том, почему и где проведена линия для того, что является объектом, а что нет?
Темный тамплиер

1

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

Вы можете реализовать дизайн "OO" (рабочий стол Gnome, пожалуй, лучший пример OO, выполненного на чистом C), я даже видел, как это делается с COBOL!

Однако возможность реализовать проектную дозу ОО не делает язык ОО. Пуристы утверждают, что Java и C ++ на самом деле не являются объектно-ориентированными, так как вы не можете переопределять или наследовать базовые «типы», такие как «int» и «char», а Java не поддерживает множественное наследование. Но поскольку они являются наиболее широко используемыми ОО-языками и поддерживают большинство парадигм, большинство «настоящих» программистов, которым платят за создание рабочего кода, рассматривают их как ОО-языки.

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


0

Давайте просто посмотрим на определение ОО:

  • обмен сообщениями
  • Инкапсуляция
  • Позднее связывание

С не предоставляет ни один из этих трех. В частности, он не обеспечивает обмен сообщениями , который является наиболее важным.


1
Я думаю, что я должен был бы не согласиться с этим. Скорее всего, вы можете иметь обмен сообщениями в C - работать с Objective C API из C, и вы поймете это подробно - и позднее связывание может быть сделано с помощью указателей на функции, но вы не получите много синтаксического сахара, чтобы скрыть это. (Инкапсуляция на самом деле проста в C; указатели на неполные типы структур отлично справляются со своей задачей.)
Donal Fellows

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

@DonalFellows, фактическая передача сообщений в Objective-C может быть легко реализована как макрос C99. Единственное, что у компилятора есть, - это то, что он генерирует все необходимые структуры статически из нескольких строк кода высокого уровня. Большинство, если не все функции доступны из C API.
QPR

0

У ОО есть ряд ключевых ингредиентов, но основными являются то, что большая часть кода не знает, что находится внутри объекта (они видят интерфейс поверхности, а не реализацию), что состояние объекта является управляемой единицей. (т. е. когда объект перестает быть, то же самое происходит и с его состоянием), и когда некоторый код вызывает операцию над объектом, они делают это, не зная точно, что это за операция или что она включает (все, что они делают, это следуют шаблону, чтобы бросить «Сообщение» через стену).

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

struct FooImpl;
typedef struct FooImpl *Foo;

Конечно, понадобится функция, которая строит Foos (т. Е. Фабрика) и которая должна делегировать часть работы самому выделенному объекту (т. Е. Через метод «конструктор»), а также иметь способ снова избавиться от объекта (позволяя очистить его методом «деструктор»), но это детали.

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

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

Но это не значит, что C является языком OO. Ключевым моментом является то, что C оставляет вам всю сложную работу по написанию соглашений и механизма рассылки самостоятельно (или использует стороннюю библиотеку). Это много работы. Он также не обеспечивает синтаксическую или семантическую поддержку, поэтому реализация полной системы классов (с такими вещами, как наследование) была бы излишне болезненной; Если вы имеете дело со сложной проблемой, которая хорошо описана в ОО-модели, ОО-язык будет очень полезен при написании решения. Дополнительная сложность может быть оправдана.


0

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

Начнем, скажем, с сокрытия информации. В C мы можем достичь этого, просто скрывая определение структуры и работая с ней через непрозрачные указатели. Это фактически моделирует publicпротив privateразличия полей данных , так как мы получаем с классами. И это достаточно просто сделать и вряд ли анти-идиоматично, так как стандартная библиотека C сильно зависит от этого, чтобы добиться сокрытия информации.

Конечно, вы теряете возможность легко контролировать, где именно структура размещается в памяти, используя непрозрачные типы, но это только заметное различие между, скажем, C и C ++. C ++, безусловно, является превосходным инструментом при сравнении его способности программировать объектно-ориентированные концепции на C, сохраняя при этом контроль над макетами памяти, но это не обязательно означает, что Java или C # превосходят C в этом отношении, поскольку эти два делают вас полностью теряет способность контролировать, где объекты размещены в памяти.

И мы должны использовать такой синтаксис, как fopen(file, ...); fclose(file);в отличие от file.open(...); file.close();большого возгласа. Кто на самом деле заботится? Может быть, просто тот, кто сильно полагается на автозаполнение в своей IDE. Я признаю, что это может быть очень полезной функцией с практической точки зрения, но, возможно, не такой, которая требует обсуждения того, подходит ли язык для ООП.

Нам не хватает возможности эффективно внедрять protectedполя. Я полностью подчинюсь там. Но я не думаю, что есть конкретное правило, которое гласит: « Все ОО-языки должны иметь функцию, позволяющую подклассам получать доступ к членам базового класса, которые по-прежнему недоступны для обычных клиентов ». Кроме того, я редко вижу варианты использования для защищенных пользователей, которые, по крайней мере, немного не подозревают о том, что могут стать препятствием на пути обслуживания.

И, конечно, мы должны «эмулировать» ОО-полиморфизм с помощью таблиц функциональных указателей и указателей на них для динамической отправки с небольшим дополнительным шаблоном для инициализации этих аналогичных vtablesи vptrs, но немного шаблонного шаблона, который никогда не вызывал у меня большого горя.

Наследование во многом аналогично. Мы можем легко смоделировать это с помощью композиции, и во внутренней работе компиляторов все сводится к одному и тому же. Конечно, мы теряем безопасность типов, если мы хотим понизить рейтинг , и я бы сказал, что если вы вообще хотите понизить рейтинг , пожалуйста, не используйте для этого C, потому что то, что люди делают в C для эмуляции понижения, может быть ужасным для типа. с точки зрения безопасности, но я бы предпочел, чтобы люди вообще не унывали . Безопасность типов - это то, что вы легко можете пропустить в C, так как компилятор предоставляет столько возможностей для интерпретации вещей, как просто биты и байты, жертвуя возможностью отлавливать возможные ошибки во время компиляции, но некоторые языки считаются объектно-ориентированными. даже статически не напечатано.

Так что не знаю, я думаю, что все в порядке. Конечно, я бы не использовал C, чтобы попытаться создать крупномасштабную кодовую базу, которая соответствует принципам SOLID, но это не обязательно из-за ее недостатков в объектно-ориентированном фронте. Многие функции, которые мне не хватало бы, если бы я попытался использовать C для таких целей, были бы связаны с языковыми функциями, которые не считаются непосредственно необходимыми для ООП, такими как строгая безопасность типов, деструкторы, которые автоматически вызываются, когда объекты выходят из области видимости, оператор перегрузка, шаблоны / шаблоны и обработка исключений. Это когда я скучаю по тем вспомогательным функциям, которые мне доступны для C ++.


1
Я не уверен, что конструкторы не могут считаться необходимым условием для ООП. Частью основной сущности инкапсуляции является возможность обеспечения инвариантов для объекта. И это требует умения правильно инициализировать объект в этих инвариантах. Для этого требуется конструктор: одна или несколько функций, так что вы не можете сказать, что объект существует, пока не будет вызвана хотя бы одна из них.
Никол Болас

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

Все, что нам нужно для поддержки инвариантов struct Fooв таком случае, - это обеспечить, чтобы внешние элементы не могли получить доступ к их элементам данных и не могли их изменить, что сразу дают непрозрачные типы (объявленные, но не определенные для внешнего мира). Возможно, это более сильная форма сокрытия информации, по сравнению с pimplC ++.

Да, я знаю, как люди реализуют ООП в C, спасибо. Моя точка зрения заключалась в том, что ваше утверждение о том, что конструкторы "непосредственно не считаются необходимым условием для ООП", ошибочно.
Николь Болас

Я понимаю, позвольте мне исправить это ... но в таком случае можно ли сказать, что C обеспечивает (адекватную?) Поддержку деструкторов и конструкторов?

-1

Неплохой вопрос.

Если вы собираетесь называть c языком OO, вам нужно будет также назвать почти все процедурные языки OO. Так что это сделало бы этот термин бессмысленным. c не имеет языковой поддержки для OO. Если имеет структуры, но структуры typesнет классов.

На самом деле c не имеет много возможностей по сравнению с большинством языков. В основном это скорость, простота, популярность и поддержка, включая тонны библиотек.

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