Как разработчик Linux (на стороне сервера), я не знаю, где и почему я должен использовать C ++.
Когда я иду на выступление, первый и последний выбор - C.
Когда «производительность» не является главной проблемой, языки программирования, такие как Perl и Python, были бы хорошим выбором.
Почти все приложения с открытым исходным кодом, которые я знаю в этой области, были написаны на C, Perl, Python, скриптах Bash, AWK или даже PHP, но никто не использует C ++.
Я не обсуждаю другие области, такие как GUI или веб-приложения, я просто говорю о Linux, CLI и демонах.
Есть ли удовлетворительная причина для использования C ++?
Ответы:
И это то, где вы должны отступить. Теперь, я не могу, вообще , говорить на развитие сервера. Возможно, нет действительно веской причины предпочитать C ++ альтернативам.
Но, вообще говоря, причина использования C ++, а не других языков, действительно заключается в производительности. Причина в том, что C ++ предлагает средства абстракции, которые, в отличие от всех других известных мне языков, не влияют на производительность во время выполнения.
Это позволяет писать очень эффективный код, который все еще имеет очень высокий уровень абстракции.
Рассмотрим обычные абстракции: виртуальные функции, указатели на функции и идиома PIMPL. Все они основаны на косвенном обращении, которое во время выполнения разрешается арифметикой указателя. Другими словами, это влечет за собой снижение производительности (как бы мало это ни было).
C ++, с другой стороны, предлагает механизм косвенного обращения, который не требует затрат (производительности): шаблоны. (Это преимущество оплачивается за счет (иногда чрезвычайно) увеличенного времени компиляции.)
Рассмотрим пример универсальной функции сортировки.
В C функция
qsort
принимает указатель на функцию, которая реализует логику, по которой элементы упорядочены относительно друг друга.Arrays.sort
Функция Java поставляется в нескольких вариантах; один из них сортирует произвольные объекты и требует, чтобы емуComparator
был передан объект, который во многом похож на указатель на функцию в Сиqsort
. Но есть еще несколько перегрузок для «нативных» типов Java. И у каждого из них есть своя копияsort
метода - ужасное дублирование кода.Java иллюстрирует общую дихотомию: либо у вас есть дублирование кода, либо у вас возникают накладные расходы во время выполнения.
В C ++
sort
функция работает так же, какqsort
в C, с одним небольшим, но принципиальным отличием: компаратор, который передается в функцию, является параметром шаблона . Это означает, что его вызов может быть встроенным . Нет необходимости в косвенном сравнении двух объектов. В тесной петле (как в данном случае) это может существенно изменить ситуацию.Не удивительно, что
sort
функция C ++ превосходит C,sort
даже если базовый алгоритм такой же. Это особенно заметно, когда логика сравнения дешевая.Теперь я не говорю, что C ++ априори более эффективен, чем C (или другие языки), и что он a priori предлагает более высокую абстракцию. Что он предлагает, так это абстракцию, которая очень высока и невероятно дешева в то же время, так что вам часто не нужно выбирать между эффективным и повторно используемым кодом.
источник
Arrays.sort
реализации Java ). Только вы теряете преимущество высокой абстракции. Это не конкретный недостаток шаблонов, это недостаток дублирования кода в целом. Кроме того, это не имеет значения, поскольку в тесных циклах обычно загружается один и тот же код.vector.push_back
дляvector<int>
и другой дляvector<float>
, но при работе с avector<int>
, есть небольшая причина, почемуvector<float>
код будет в кеше инструкций. Поэтому я не вижу, как это действительно имеет значение. Каждый создание отдельных шаблонов высоко оптимизировано и, как правило, более компактно, чем универсальные реализации,Я вижу слишком много программистов на C, которые ненавидят C ++. Мне потребовалось некоторое время (годы), чтобы постепенно понять, что хорошо, а что плохо. Я думаю, что лучший способ выразить это так:
Меньше кода, никаких накладных расходов, больше безопасности.
Чем меньше кода мы напишем, тем лучше. Это быстро становится ясно всем инженерам, которые стремятся к совершенству. Вы исправляете ошибку в одном месте, а не во многих - вы выражаете алгоритм один раз и повторно используете его во многих местах и т. Д. У греков даже есть высказывание, восходящее к древним спартанцам: «сказать что-то меньшим количеством слов означает что вы мудры в этом ". И дело в том, что при правильном использовании C ++ позволяет вам выражать себя в гораздо меньшем количестве кода, чем C, не затрачивая при этом скорости выполнения, при этом будучи более безопасным (то есть перехватывая больше ошибок во время компиляции), чем C.
Вот упрощенный пример из моего рендерера : при интерполяции значений пикселей по линии сканирования треугольника. Я должен начать с координаты X x1 и достичь координаты X x2 (слева направо от треугольника). И на каждом шаге, на каждом пикселе, который я пропускаю, я должен интерполировать значения.
Когда я интерполирую окружающий свет, который достигает пикселя:
Когда я интерполирую цвет (называемый «затенением Гуро», где поля «красный», «зеленый» и «синий» интерполируются значением шага в каждом пикселе):
При рендеринге с затенением «Фонг» я больше не интерполирую интенсивность (ambientLight) или цвет (красный / зеленый / синий) - я интерполирую нормальный вектор (nx, ny, nz) и на каждом шаге приходится -считать уравнение освещения на основе интерполированного вектора нормали:
Теперь первым инстинктом программистов на Си будет «черт возьми, напиши три функции, которые интерполируют значения и вызывают их в зависимости от установленного режима». Прежде всего, это означает, что у меня есть проблема с типом - с чем я работаю? Являются ли мои пиксели PixelDataAmbient? PixelDataGouraud? PixelDataPhong? Ой, подождите, говорит эффективный программист на C, используйте союз!
..и тогда у вас есть функция ...
Чувствуете ли вы хаос?
Прежде всего, одна опечатка - это все, что нужно для сбоя моего кода, так как компилятор никогда не остановит меня в разделе функции «Гуро», чтобы фактически получить доступ к «.a». (окружающие) значения. Ошибка, не обнаруженная системой типов C (то есть во время компиляции), означает ошибку, которая проявляется во время выполнения и требует отладки. Вы заметили, что я обращаюсь
left.a.green
в расчет "dgreen"? Компилятор, конечно, не сказал вам этого.Затем повсюду повторение -
for
цикл существует столько раз, сколько существует режимов рендеринга, мы продолжаем делать «правый минус левый, разделенный на шаги». Гадкий и подверженный ошибкам. Вы заметили, что я сравниваю, используя «i» в цикле Гуро, когда я должен был использовать «j»? Компилятор опять молчит.А как насчет if / else / ladder для модов? Что если я добавлю новый режим рендеринга через три недели? Я буду помнить, чтобы обрабатывать новый режим во всем "if mode ==" во всем моем коде?
Теперь сравните вышеупомянутое уродство с этим набором структур C ++ и функцией шаблона:
Теперь посмотри на это. Мы больше не делаем объединение типов супов: у нас есть определенные типы для каждого режима. Они повторно используют свой общий материал (поле «x»), наследуя от базового класса (
CommonPixelData
). И шаблон заставляет компилятор CREATE (то есть генерировать код) тремя различными функциями, которые мы написали бы сами в C, но в то же время очень строго относимся к типам!Наш цикл в шаблоне не может работать и обращаться к недопустимым полям - компилятор будет лаять, если мы это сделаем.
Шаблон выполняет обычную работу (цикл, увеличивающийся на «шаг» в каждый раз) и может делать это так, что просто НЕ МОЖЕТ вызывать ошибки во время выполнения. Интерполяция по типу (
AmbientPixelData
,GouraudPixelData
,PhongPixelData
) делаются с ,operator+=()
что мы добавим в структурах - которые в основном диктуют , как интерполируются каждый тип.И вы видите, что мы сделали с WorkOnPixel <T>? Мы хотим сделать разные работы для каждого типа? Мы просто называем шаблонную специализацию:
То есть - функция для вызова определяется по типу. Во время компиляции!
Чтобы перефразировать это снова:
WorkOnPixel
версий, код C ++ будет БЫСТРЕЕ, чем C, потому что компилятор встроитWorkOnPixel
специализацию шаблона конкретного типа. вызов!Меньше кода, никаких накладных расходов, больше безопасности.
Означает ли это, что C ++ является основным и конечным языком? Конечно, нет. Вы все еще должны измерить компромиссы. Невежественные люди будут использовать C ++, когда им следовало написать скрипт на Bash / Perl / Python. Новички в C ++, удовлетворяющие триггерам, создадут глубоко вложенные классы с виртуальным множественным наследованием, прежде чем вы сможете их остановить и отправить упаковку. Они будут использовать сложное метапрограммирование Boost, прежде чем поймут, что в этом нет необходимости. Они будут по- прежнему использовать
char*
,strcmp
и макросы, аstd::string
и шаблоны.Но это говорит только о том, что ... смотри, с кем ты работаешь. Там нет языка, чтобы оградить вас от некомпетентных пользователей (нет, даже не Java).
Продолжайте изучать и использовать C ++ - только не переусердствуйте.
источник
RAII для победы ребенка.
Серьезно, детерминированное уничтожение в C ++ делает код намного понятнее и безопаснее без каких-либо накладных расходов.
источник
Шаблоны и STL. Вы тратите немного времени на сборку (и некоторые потенциально непонятные сообщения об ошибках) на множество полезных инструментов для абстракции и экономии труда, без заметного снижения производительности во время выполнения (хотя двоичный объем может быть немного больше).
Требуется некоторое время, чтобы обернуть вашу голову (у меня ушло пару лет, прежде чем она щелкнула), но когда вы это сделаете, это может сделать жизнь намного проще.
Обработка текста в C ++ на несколько порядков менее болезненна, чем в C.
источник
Да.
Если вам нужна эффективность исполняемых файлов, вы переходите на C или C ++, поэтому я сосредоточусь на этом.
Еще до того, как шаблоны стали обычным явлением, я предпочитал использовать C ++ вместо C для типов исполняемых файлов, которые вы обсуждали еще в середине 1990-х годов, по двум очень простым причинам: полиморфизм объектов и RAII .
Я использовал полиморфные объекты C ++ для всех интересных вещей. Например, я работал над встроенной системой Linux с оверлеями кадрового буфера на процессорах OMAP и XScale ARM. Две аппаратные архитектуры имеют различные функции наложения с очень разными API. Я использовал общий виртуальный базовый класс «Наложение» для представления идеализированного представления наложений, а затем написал классы «OmapOverlay» и «XScaleOverlay», которые были созданы соответствующим образом во время выполнения в зависимости от архитектуры, в которой был обнаружен код, в котором он выполнялся.
Для упрощения, RAII - это идея, что вы выделяете ресурсы, связанные с объектом, во время конструктора объекта или, возможно, позже, во время жизни объекта, и ресурсы освобождаются или освобождаются в деструкторе объекта. Это действительно хорошо в C ++, потому что объекты, которые являются автоматическими переменными, разрушаются, когда они выходят из области видимости. Для тех, кто одинаково компетентен в C и C ++, гораздо проще избежать утечек ресурсов и памяти в C ++. Вы также не видите много кода C ++ с очень распространенным C-мемом метки в конце функции, предшествующей группе вызовов
free()
, и различныеgoto
элементы в функциональном блоке, прыгающие туда.Я полностью осознаю, что вы можете делать все эти вещи с C - это просто намного больше работы, намного больше строк кода, и то, что вы получите, намного уродливее и часто труднее для понимания. Есть код полиморфизма во всех внутренних частях X-сервера , и, мужик, он неясный и странный, и его часто трудно отследить.
Я также много работаю с технологиями GNOME, такими как GTK + и Clutter, все из которых написаны на C с использованием системы GObject. GObject похож на объектную систему C ++ с снятым красивым прикрытием и открытыми всеми уродливыми внутренностями, и обычно требуется полдюжины строк кода для выполнения того, что будет делать однострочный вызов метода C ++. В настоящее время я пишу некоторые из них
ClutterActors
, и хотя математика действительно интересна, я постоянно думаю: «Все это было бы намного более кратким и понятным в C ++».Я также часто думаю: «Знаете, если бы я писал это на C ++ вместо C, я бы сидел в гостиной и смотрел на« Разрушителей легенд » с моей женой, а не сидел в своем офисе в 9 вечера».
источник
C ++ примерно такой же быстрый, как C (некоторые вещи быстрее, некоторые медленнее), и он предлагает лучшие абстракции и организацию. Классы работают аналогично примитивным типам, позволяя использовать большие объемы кода, не принимая во внимание. Перегрузка операторов и шаблоны позволяют писать код, который функционирует лучше, если изменяется представление данных. Исключения могут упростить обработку ошибок. Компилятор может использоваться для проверки большего количества вещей во время компиляции.
Цена, которую вы платите за это, довольно неприятная кривая обучения, и в ней легче делать тонкие ошибки, чем в большинстве других языков, с которыми я знаком.
Так что я не могу сказать, стоит ли вам изучать то, что вы делаете сейчас. Конечно, вы можете обойтись с комбинациями Python или Perl и C, но C ++ предлагает как абстракцию, так и производительность в одном сложном для использования пакете.
источник
restrict
используется для исключения из оптимизации псевдонимов, так как же это поможет ускорить процесс ? а что такое "параметр статического массива"? и как "стиль" влияет на производительность?T (&arr)[n]
илиstd::array<T, n>
- придется исследовать этот вопрос еще, так как там не так много информации. Это имеет смысл в умных указателях, безусловно, хороший пример. Если кодирование на равных игровых полях, мы не будем использовать исключения, поэтому не будет понесено никаких потенциальных затрат ... однако я подозреваю, что вы могли бы сослаться на то, как, когда сторонние библиотеки входят в картину, много предположений в опасности.Я рассматриваю C ++ как язык 1990-х, язык ушедшей эпохи.
В то время он был большим, потому что предлагал языковые конструкции и механизмы более высокого уровня по более низкой цене с точки зрения производительности. Это был универсальный инструмент для разработки всего, от приложений адресной книги до программного обеспечения авионики, и это вдохновило OO. ООП решило проблему голода и СПИДа, и да, я обвиняю С ++ в том, что в конце 1990-х годов, когда я впервые начал программировать, я пытался «промыть мозги», что любой не-ОО-язык не стоит изучать.
Теперь, когда аппаратное обеспечение продвинулось так много, и появились новые, современные языки, я не вижу, чтобы C ++ оставался актуальным выбором для большинства прикладных программ, за исключением программного обеспечения с высокими вычислительными возможностями, где вам все еще нужна некоторая абстракция (игры, симуляции физики, системы CAD и т. Д. ). Даже последнего можно избежать, если вы пишете компактный модульный движок на C и имеете высокоуровневую логику приложения, делегированную на аккуратный язык сценариев.
Если вам нужно перейти к металлу, используйте C разумно, и когда вам нужно перейти на высокий уровень, сделайте это на современном языке, который не объявляет инкапсуляцию, в то время как вы можете свободно изменять каждый байт через указатель.
источник
По словам Линуса , нет:
источник
Я не думаю, что есть веская причина использовать C ++. Если вы хотите заняться ОО-программированием, вы можете вместо этого использовать Python и написать части, которые требуют быстрой работы на C.
РЕДАКТИРОВАТЬ: Есть другие языки, которые хорошо взаимодействуют с C, так что если вам не нравится Python, есть альтернативы.
источник
Есть ли причина использовать C ++? Конечно.
Некоторые люди могут просто предпочесть использование C ++ другим параметрам. Спрашивать, есть ли причина использовать C ++, все равно, что спрашивать, почему нам нужно иметь сотни видов мороженого. Не всем нравится просто придерживаться ванили.
Если разработчики уже очень хорошо разбираются в C ++, вопрос для них может заключаться не в том, «зачем его использовать?», А в том, почему? Кажется, сейчас в SO происходит такая модная анти-C ++ вещь, но, верьте или нет, не все подписываются на это. Некоторые люди могут просто любить C ++ лучше, чем другие языки.
Есть ли C ++ необходимо использовать для приложений? Конечно, нет. Но этот же точный вопрос можно задать и для любого другого языка. Очень и очень мало случаев, когда для приложения необходимо использовать определенные языки.
источник
Я просто переключаюсь с C на C ++, и я думаю, что выгода значительна, даже если вам не нужны шаблоны и ООП.
источник
Я удивлен, что никто еще не упомянул об этом, но C ++ представил нам ссылки , которые почти решают все проблемы и ловушки указателей:
Вместо:
Намного безопаснее и проще ... и без затрат на передачу по стоимости.
источник
Где и почему обычно собираются быть:
Для программирования на стороне сервера вы часто можете выбирать из множества языков, скомпилированных или интерпретированных. Обычно выбор языка зависит от того, на какой платформе вы или ваша команда будете наиболее эффективны. Или, если у вас еще нет команды, наличие навыков на рынке.
С другой стороны, я не совсем понимаю, решил ли использовать C / C ++ на основе производительности (только), поскольку многие языки сценариев расширяемы с помощью C / C ++. Вы получаете преимущество языка быстрой разработки в сочетании с возможностью переноса медленных частей в расширения C / C ++. Конечно, если вы занимаетесь системным программированием, где каждая операция имеет значение, это понятно, но в большинстве приложений я не понимаю этого.
источник
C ++ против Python против Perl не может быть легко судить. Это зависит от проекта и требований.
C ++ имеет арсенал утилит с давних времен, работающих на многих платформах. Но больно начинать ходить по потокам, просто передавая String в Integer и наоборот.
С ++, с другой стороны, ужасно разбирается в зависимости от библиотек. Как только вы что-то скомпилируете в GCC X или VC ++ Y, вы не можете полагаться на то, что код будет выполняться следующей версией этих инструментов. Тот же ад в Windows, такой же ад и в Unix.
Perl берет свою силу из мира Unix, но особенно как инструмент регулярных выражений. Это то, что используется большую часть времени. Наряду с некоторыми довольно серьезными инструментами, которые даже Java не может сделать это обычным способом (посмотрите, как загрузить файл на веб-сервер), Perl «просто делает это».
Python - это простой, гибкий и динамичный язык. Настолько легко, что вы можете отправить целое число в функцию, сценарий ожидает строку, но вы можете получить результат! Неожиданно, но результат. Так что программист должен быть очень осторожен. IDLE предлагает некоторую отладку, но когда вы подключены к системе TELNET или подключены по трем уровням SSH и хотите найти свою проблему, отладчик не будет рядом с вами. Но он может быстро выполнить большую математическую работу.
Java - это экосистема модных слов, инопланетных технологий и громких слов, и когда вы хотите просто загрузить файл на веб-сервер, вы обнаружите, что вы можете сделать это, только если на сервере есть JSP . Если вы хотите вызвать системные библиотеки или системные функции, такие как мониторинг, вы обнаружите, что вам нужно много копать. И, возможно, чтобы достичь JNI и ОК ... вы думаете тогда ... "Почему, Господь?"
Кроме того, Java - отличный инструмент для бизнес-пакетов и многопоточности, мне он очень понравился.
Быстро составьте программу и покажите свое резюме «О, я тоже знаю эту технологию» и вашему желающему быть боссом, удивитесь! Несмотря на то, что технология может быть не так нужна ... (Хорошо, ребята, я ненавижу Spring Framework ....)
источник
При выборе языка следует помнить о том, какую пользу вы получите от его использования, и сколько времени потребуется для его получения.
Основная идея между такими языками, как python и perl, состоит в том, чтобы делать больше с меньшими затратами рабочего времени, но с большим количеством процессорного времени. На самом деле вы потратите больше времени на написание Python или Perl-скрипта, чем он будет выполнен, но вы поняли мою точку зрения.
Преимущество C / C ++ состоит в том, что они быстрые, но за счет синтаксиса и строгой типизации: вам придется многое делать самостоятельно, чтобы компьютер не выбирал его во время компиляции.
Когда вы создаете код, некоторые строки будут выполняться намного больше, чем другие, и именно эти строки создают проблему. С другой стороны, весь остальной код, на который вы потратили много времени, выполняется гораздо реже. Возможно, вы слышали это, но это печально известное правило 80/20, и вы не сможете обойти это правило.
Решением этой проблемы является использование более простого языка (под более простым, я имею в виду более дружественный к разработчику: меньше набирайте текст, ленивая интерпретация, много уже существующих подпрограмм и т. Д.) Для выполнения всего вашего кода.
Вы сделаете это так быстро, по сравнению с тем, если бы вы делали это с C или C ++, потребовалось бы гораздо больше болей в мозгу.
Ваша программа будет работать медленно, но с помощью профилировщика вы изолируете часть, которая выполняется 80% времени, и вы делаете это с C или C ++.
Прормируя таким образом, вы сэкономили много времени, и ваша программа настолько же эффективна, как и быстра, имеет гораздо меньше шансов утечки памяти, и вы сэкономили время.
Языки сценариев были разработаны, чтобы быть на стороне разработчика, но оптимизация все еще возможна. Конечно, вы можете быть волшебником по дизайну, или вуду STL, или даже воином, и, возможно, монахом из Хаскелла. Но языки заставляют нас говорить с компьютерами, языки не созданы для того, чтобы мы были компьютерами!
источник
Linux? А как насчет «объектно-ориентированного Паскаля» или «D»?
Предложения:
источник
C ++, который я использую, называется C с классами!
источник
Там на самом деле один ответ на все вопросы, сформированные следующим образом. Лучшая причина использовать технологию X вместо технологии Y (где X и Y находятся примерно на одном уровне [как почти все современные языки программирования]), потому что вы уже знаете X и не знаете Y.
(но после прибытия Хаскелла не было никаких причин использовать что-либо еще)
источник
Нет, совсем нет. Если вам не нужна производительность и есть библиотека, которую вы можете использовать на другом языке, не беспокойтесь о C / C ++. Я делаю это только сейчас, когда нацеливаюсь на встроенные системы, которые не могут (легко?) Запускать языки. Иногда я использую C, потому что я пишу плагин, но на самом деле нет.
Однако я бы не использовал Python, Perl и т. Д., Чтобы избежать использования C. На самом деле я предпочитаю C #, потому что мне нравится хорошая библиотека (которая является сильной стороной .NET), и мне нравятся статически типизированные языки. Бу хорошая альтернатива. Но на самом деле Haskell , OCaml , D , ML и все в порядке.
источник