Я прочитал где-то в одном из ответов на вопрос здесь (не помню, какой), что C ++ не подходит для объектно-ориентированного программирования. Были некоторые упоминания о том, что вы можете использовать его функцию или что-то в этом роде, но не в чисто ООП-смысле (на самом деле я не совсем понял, что имел в виду этот человек).
Есть ли в этом доля правды? если так, то почему?
c++
object-oriented
gablin
источник
источник
Ответы:
Как описано в разделе Так, что * на самом деле * Алан Кей имел в виду под термином «объектно-ориентированный»? Алан Кей считал, что передача сообщений является важным битом ООП, но это тот бит, которого не хватает в «C с классами» (который позже стал C ++). C ++ просто структурирован с небольшим поведением, тогда как объекты в Smalltalk или Objective-C «интеллектуальны» в том смысле, что они могут решать, что они делают с отправляемыми сообщениями. Если объект Smalltalk-esque получает сообщение, для которого у него нет реализации, он может лениво добавить его, переслать сообщение другому объекту или выполнить любую произвольную вещь.
Что C ++ предлагает в отношении объектной ориентации, так это
virtual
методы и полиморфизм, включающие способ вызова этих методов. Когда компилятор видит тип данных (илиclass
) с виртуальными методами, он создает виртуальную таблицу со слотом для каждого виртуального метода. Подклассы, которые реализуют виртуальные методы, поместят свои реализации в правильные слоты, поэтому клиентскому коду просто нужно знать, где в виртуальной таблице искать код для выполнения, а не разрешать его полностью до конкретной функции. Это означает, что C ++ действительно имеет форму множественной диспетчеризации, хотя все это реализовано в компиляторе и не так эффективно, как система Smalltalk-esque.Если вы принимаете передачу сообщений за основу для ООП, то, хотя вы можете сделать это с C ++, это далеко не просто. OTOH, если вы используете OOP для обозначения связи данных с функциями, которые работают с этими данными, C ++ - это хорошо.
источник
Такое обсуждение беспокоит меня, потому что это звучит как толкование, люди обсуждают значение Священного Писания или американской Конституции и то, что имели в виду первоначальные авторы, как будто то, что мы думаем, не имеет значения.
Послушайте, Алан Кей был / был умным парнем, и у него была хорошая идея, которая натерлась на кучу других хороших идей и нашла свою реализацию на Smalltalk и других языках.
Он не Мессия, а ООП - это не Единственная Истинная Парадигма Программирования.
Это хорошая идея, среди многих. Есть ли в C ++ хорошие идеи, исходящие из мышления ООП? Конечно, это так.
источник
C ++ поддерживает ООП, если вы определяете ООП для обозначения инкапсуляции, наследования и полиморфизма.
Тем не менее, C ++ не особо выделяется в ООП. Одна из причин заключается в том, что полиморфизм часто зависит от объектов, размещенных в куче, с которыми (несмотря на использование интеллектуальных указателей) более естественно работать в языке с мусором.
Однако C ++ превосходит универсальное программирование. C ++ позволяет легко создавать высокоэффективный общий код с помощью методов функционального программирования на основе шаблонов.
источник
C ++ позаимствовал функции ООП от Simula. Один или несколько разработчиков Simula IIRC отметили, что C ++ - это не то, что они имели в виду.
C ++ имеет хорошие инструменты для абстракции, но это скорее язык со смешанной парадигмой, чем объектно-ориентированный язык. Объектно-ориентированные функции есть, но у вас есть выбор, который не является «строгим ООП».
Одним из непослушных «отказов», которые вы получаете в C ++, является использование раннего, а не позднего связывания для методов. Мало того, что это возможно - это по умолчанию. В Java «финал» связан, но в некотором смысле чище (он задает намерение таким образом, который не просто предотвращает тривиальные потери производительности), и он не используется по умолчанию.
В некотором смысле, C ++ показывает признаки того, что это ранний эксперимент, который все еще здесь. Тем не менее, это все еще хороший инструмент с множеством преимуществ, которых вы не получите на других языках ООП.
источник
Принуждение всего к тому, чтобы быть частью класса, не обязательно приводит к хорошему ОО-коду.
Попросите плохого процедурного программиста программировать на Java, и он, возможно, возьмет где-нибудь класс, даст ему статический метод main и вставит в него 1000 строк кода. Я знаю, что видел это.
У Java есть оператор switch. Я видел
switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }
и т.д. в C ++ и Java-коде.C ++ поддерживает многие концепции ОО, но его стандарт не определяется им, однако, я думаю, многое зависит от вашей цели.
Основная «плохая» семантика в C ++ позволяет копировать классы, в результате чего объект превращается в другой. Вы можете отключить это, но затем вы не можете вернуть один из функции. К счастью, это решено в C ++ 0x.
источник
ООП - это не просто уверенность в том, что все в классе. Вполне возможно написать не OO-код на «чисто OO-языке». Например, «main» часто указывается как глобальная функция, но изобретение класса, содержащего только статический метод main, совсем не как OO.
C ++ лучше всего работает с различными вещами; это не должно удивлять, так как большинство хороших вещей работают лучше всего. Часто ООП является одним из тех очень полезных инструментов.
источник
C ++ можно использовать для ООП, но он не такой «чистый», как что-то вроде Smalltalk. C ++ также позволяет вам делать не-ООП, о чем люди могут говорить.
источник
Хотя я не согласен с мнением, это правда, что система типов C ++ не является чистой ООП, а не «все является объектом». Числа (в частности) не могут быть расширены так легко, как, например, в Smalltalk. Например, вы не можете переопределить значение «2 + 2» (хотя вы можете переопределить значение «два + два»).
Но большинство людей, вероятно, имеют в виду, что многие люди пишут не объектно-ориентированный код на C ++, но считают, что, поскольку они используют язык «ООП», они объектно-ориентированы. Это не правда. Но, на мой взгляд, вы можете написать отвратительный императивный код на Smalltalk и не превзойти приличный дизайн ООП в C ++.
источник
Совершенно обоснованное возражение Алана Кея против C ++ заключалось в том, что это был макроязык над C.
Понятие «передача сообщений» - это просто идея о том, что экземпляры классов хранятся в памяти и что они предоставляют методы, которые можно вызывать. Передача сообщений * моделируется "в C ++ с использованием таблиц vtables, содержащих указатели на функции.
Сказать, что передача сообщений не существует в C ++, неточно, но точнее сказать, что передача сообщений является неотъемлемой частью других языков, таких как smalltalk и Java, потому что язык не обрабатывает стороннюю конструкцию и не прививает ее непосредственно в C.
Это очень семантический аргумент в пользу языкового дизайна, который, как я подозреваю, немного превышает уровень опыта спрашивающего.
Тем не менее, есть тысячи причин ненавидеть C ++ и очень мало причин любить его.
Вместо того, чтобы искать идеальный молоток и идеальный гвоздь, найдите идеальный дом для строительства, а затем найдите правильные инструменты ... это требует опыта.
Также важно помнить, что в системном программировании то, чего боится Алан Кей, не является «чистым ООП», на самом деле является сильной стороной C ++. Каждому свое...
источник
На мой взгляд, это не столько проблема определения, сколько проблема юзабилити.
Объекты - это абстракция, предназначенная для облегчения чтения, написания и анализа сложных программ. Для практического программиста то, соответствует ли язык всем критериям определенного формального определения «объектно-ориентированного» (кажется, что есть несколько конкурирующих!), Не так важно, как подходящие инструменты, которые он предлагает, для размышлений ваша программа с точки зрения указанных объектов - т.е. фактически пожинает предполагаемые преимущества производительности ООП.
В C ++ объекты представляют собой чрезвычайно утечку абстракций, часто заставляющую программистов сталкиваться с неприятными проблемами, связанными с тем, как эти объекты структурированы в памяти, - проблемами, которые больше напоминают кодирование на прямом C, чем в других языках ООП. Например, C ++ Часто задаваемые вопросы предлагает эту критику (среди прочих):
C ++ является объектно-ориентированным, но неприятным и неполным: его пользователи должны приложить немало усилий, чтобы убедиться, что их данные на самом деле ведут себя как «реальные» объекты, а не как ошибочные биты. Тем не менее, много кода было написано на C ++ за время его жизни, большая часть которого использует классы и динамическую диспетчеризацию, так что это само собой разумеется, что вы можете использовать для практического ООП.
источник
Есть причина, по которой у Грэма Ли было больше всего голосов. Повторюсь, похоже, что класс C ++ на самом деле не является объектом в том смысле, что он не выполняет передачу сообщений. Я думаю, это то, что запутывает людей, когда они изучают C ++ или упс. Людям говорят, что объектно-ориентированным является «это», а затем говорят, что C ++ делает это по-другому. Ну, C ++ никогда не делал ООП иначе. Если вы думаете так, вы никогда не будете ценить классы C ++ за то, для чего они предназначены, и это то, что они являются просто улучшением процедурной парадигмы путем включения абстракции и динамического поведения. Таким образом, классы C ++ являются процедурно-процедурными, они просто улучшают процедурную парадигму или, скорее, являются более продвинутой версией структуры C.
источник
Стив Йегге сказал это лучше всего :
Объектная система в C ++ настолько жестко запрограммирована и исправлена во время компиляции, что она очень далека от первоначального понятия ООП, которое включает, среди прочего, передачу сообщений, самоанализ, отражение, динамическую диспетчеризацию и позднее связывание. Единственное, что общего у C ++ и Smalltalk - это немного словарного запаса.
источник