Зачем мне изучать C ++ 11, знавший C и C ++? [закрыто]

28

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

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

Я знаю, что когда-нибудь в будущем, когда вы скажете, C ++, все примут C ++ 11. Так же, как когда вы говорите «C», вы, скорее всего, имеете в виду «C99» Это заставляет меня задуматься об изучении C ++ 11. В конце концов, если я захочу продолжить писать код на C ++, мне, возможно, в какой-то момент придется начать использовать эти функции просто потому, что это сделали мои коллеги.

Взять, к примеру, C. По прошествии стольких лет все еще много людей изучают и пишут код на C. Почему? Потому что язык хороший. Что означает хорошее, так это то, что для создания хорошего языка программирования следует много правил. Таким образом, помимо того, что он мощный (что легко или сложно, почти все языки программирования есть), C является обычным и имеет несколько исключений, если они есть. C ++ 11 однако я так не думаю. Я не уверен, что изменения, внесенные в C ++ 11, делают язык лучше.

Итак, вопрос: зачем мне учиться C ++ 11?


источник
3
Я понимаю, что на этом форуме не должно быть скандалов C ++ 11, и я полностью согласен с этим: каждый разработчик имеет право иметь свой собственный вкус в отношении языков программирования и инструментов. Однако для меня существует гораздо более практическая проблема: я разработчик C ++ и мне не нравится C ++ 11, буду ли я вынужден использовать C ++ 11 или уйти с рынка / перейти на другой язык внутри несколько лет?
Джорджио
Ну, я немного подумал об этом, конечно, есть более современные языки с нуля, такие как язык программирования D или Go. Они могут быть подходящими для вашей проблемной области, проще, более последовательными и т. Д. Однако доля рынка. Ни один из ключевых игроков в отрасли не поддерживает D и даже Go, похоже, является одним из «экспериментов» Google, поэтому мотивация C + +11 должны быть полезными улучшениями, которые позволят вам писать более читабельный, безопасный и быстрый код, а также широкой отраслевой поддержкой.
Нильс
@giorgio, в течение последних двух лет я перестал использовать C ++ так же часто, как раньше (в основном из-за понимания религиозных фанатов C ++, чтения ответов на этот вопрос), но все же я также работал в библиотеке C ++, которую я охотно использовал C ++ 11 для. Мой опыт был таким: C ++ 11 обращается ко многим дрянным углам C ++, и это достойно восхищения, и это действительно улучшает его. У этого способа есть свои дрянные углы (см. Оригинальный неотредактированный пост). Тем не менее, эти дрянные углы, кажется, не в порядке, если вы делаете вещи «обычным образом» (например, не храните лямбду для будущего использования).
@giorgio, я имею в виду то, что C ++ 11 вначале может выглядеть плохо, на самом деле сам C ++ выглядит ужасно, но если у вас все в порядке с C ++, вам, вероятно, тоже понравится C ++ 11. Просто не дотрагивайтесь до его дрянных частей, и вам это действительно понравится.
@anon: Один из способов избавиться от дурацких частей языка - покончить с прошлым и начать новый язык, как Apple делает со Swift (назвать только один из многочисленных примеров). Взаимодействие с унаследованным кодом может осуществляться с помощью отдельной компиляции. Проблема с C ++ заключается в том, что он расширяется до бесконечности, возможно, потому, что он поддерживается сообществом поклонников, которые неукоснительно верят, что C ++ является единственным истинным языком. Итог: я нашел C ++ 03 немного дурацким, но он выполнил свою работу, особенно благодаря таким библиотекам, как Qt и boost. С другой стороны, я буду держать руки подальше от C ++ 11.
Джорджио

Ответы:

24

Вы должны изучить это, если считаете, что вам нужно будет это знать в будущем, чтобы получить работу. Если вы уверены, что останетесь конкурентоспособным в рабочей силе как C / C ++ [и все, что вы могли бы знать], тогда не изучайте это. Если ваш начальник скажет вам использовать C ++ 11, скажите «нет, я этого не делаю». Если он уволит тебя, иди работай в другом месте. Изучайте C ++ 11, когда вы предвидите, что скоро вы не сможете найти удовлетворительную работу с теми навыками, которые вы знаете в настоящее время.

Хотел уточнить мое обоснование: я не против C ++ 11. Просто сказать, что вы можете обобщить вопрос ОП: «Почему я должен учить Х». Я никогда не изучал ML, схему или haskell, потому что у меня есть работа с C и C ++. Я уверен, что эти языки кому-то полезны, но мне сейчас не выгодно учиться. Если бы кто-то предложил мне хорошие деньги для программирования на ML, я мог бы попытаться изучить это.

Timmah
источник
3
Если вы разработчик на C / C ++ и ваш босс говорит вам использовать C ++ 11, разве вы не должны просто пойти дальше и добавить это в свой арсенал? Я согласен с тем, что вам не следует тратить все свое время на изучение языков только ради их изучения, но когда ваш начальник говорит: «Изучите это», вероятно, будет хорошей идеей пойти дальше и выучить его. Это также делает вас более конкурентоспособным, в отличие от необходимости объяснять в следующем заявлении, что вас уволили за неподчинение.
Panzercrisis
Haskell ... Забавно, из-за медленного включения лямбд в C ++. : P
rbaleksandar
85

Это просто. C ++ 11 делает код значительно проще, чище писать и быстрее.

nullptrэто значительное улучшение по сравнению со старым 0. Это типобезопасно и не конвертируется, когда не должно - в отличие 0. Это хорошая вещь, nullptrкоторая не будет преобразована в int. Это вообще не имеет смысла. Знаете ли вы, что обнаружил Комитет C ++, когда они пытались это рассмотреть #define NULL nullptr? Вещи как char c = NULL;. Насколько это ужасно? Единственная причина, по которой здесь есть исключение, заключается в том, что boolон считается целочисленным типом, что довольно неправильно, но это было в C ++ и раньше, и в C. Тот факт, что nullptrне конвертируется, хорош , это здорово, и вы должны любить его.

Или как насчет ссылок и переменных шаблонов? Быстрее, более общий код. Это полная победа прямо здесь.

Как насчет улучшений библиотеки? Такие вещи , как function, unique_ptrи shared_ptrтак гораздо лучше , чем то , что было раньше, невозможно утверждать , что C ++ 03 способ лучше.

#define adding_func(x, y) ((x)+(y))

Даже отдаленно не эквивалентно. Макросы плохие по шести миллиардам причин. Я не собираюсь приводить здесь все из них, но хорошо известно, что макросов следует избегать практически во всех целях, для которых их возможно избежать. Что ты собираешься делать, когда это

#define add_twice(x) (x + x)

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

Затем вы открываете себя миру неопределенного поведения для использования внешних переменных, области действия которых уже завершены.

В функциональном API, например алгоритмах STL, ссылка справедлива. Если это сохраненный обратный вызов, то вам нужно захватить по значению. Какая бы документация у вас не была для этой функции, она должна четко указывать, что необходимо. Тот факт, что код написан в лямбде, не имеет отношения к проблеме обращения к локальным переменным - если вы передадите объект обычной функции, то у вас точно такая же проблема. И это не проблема. Вообще. Потому что это очевидно, когда вы можете и не можете ссылаться на локальные переменные.

Взять, к примеру, C. По прошествии стольких лет все еще много людей изучают и пишут код на C. Почему?

Есть много людей, которые не чистят зубы по утрам. Есть много убийц, насильников и проституток. И политики. Люди, которые совершают самоубийство. Не могли бы вы утверждать, что это делает эти мероприятия хорошими или полезными? Конечно нет. Это логическая ошибка, что только потому, что кто-то сделал это, он должен быть хорошим или полезным.

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

Если вы возьмете C или старый стиль C ++, вы не найдете много исключений.

Как насчет жалких массивов в стиле C, для простого примера? Число людей, которые не могут получить массивы и указатели прямо в своей голове, непристойно. Не говоря уже о том, что библиотека C Standard невероятно небезопасна.

Ваши основные аргументы полны логических ошибок и недоразумений.

DeadMG
источник
7
> Тот факт, что nullptr не конвертирует - это хорошо, это здорово, и вы должны любить его. Хорошо, ваше мнение, но немного успокойтесь о том, что кто-то должен любить, пожалуйста ... Следующий шаг - талибанизм юристов C ++!
Эмилио Гаравалья
5
Я думаю, что более поздняя часть вашего ответа больше о том, почему C ++ предпочтительнее, чем C. Это не подлежит сомнению. «Библиотеки C небезопасны» - как это отвечает на вопрос? Я имею в виду, конечно, что нужно изучать новые функции, которые предлагает C ++ 11, но C и C ++ НЕ предназначены для того же. Если C ++ - это сука для реализации на низком уровне, то же самое относится и к C #, Java, Python и так далее, потому что они не предназначены для такого низкого уровня. Тот факт, что C ++ компилируется в собственный код, не означает, что вы можете использовать OO и связанную с ним страницу для критического кода уровня ядра.
Яти Сагаде
11
@ Shahbaz, очевидно, что вам нужно больше узнать о языках программирования (например, о системах типов, лексической области видимости и т. Д.), Все ваши комментарии полностью не синхронизированы. Начните с этой книги: amazon.com/Theories-Programming-Languages-John-Reynolds/dp/…
SK-logic
5
@yati: C ++ имеет ту же систему модулей, что и C. Функции-члены реализованы как простые старые функции C. Виртуальные функции реализованы так же, как загрузка функций из DLL. Там нет ничего страдающего о них. И да, это определенно применимо. Для начала, ваша вера в то, что Unix - лучший, субъективна. Это 5% доли рынка говорит об обратном. А во-вторых, даже если бы я без конца обожал Unix, ни один пример не установил тенденцию. То же самое верно и для других примеров, которые вы приводите. Какие примеры? Они бессмысленны. C ++ так же подходит для процедур, как и C.
DeadMG
8
@yatisagade C ++ - это мультипарадигмальный язык, который не применяет виртуальные функции для всего, и мои программы на C ++ похожи. Его части используют объектно-ориентированный дизайн, его части функциональны и т. Д., В зависимости от того, что лучше всего решает эту конкретную подзадачу. Я ценю C ++ за добавление объектно-ориентированного стиля и C ++ 11 за значительное расширение поддержки функционального программирования.
Дэвид Стоун
29

C ++ 11 не новый язык; это только расширение / модификация C ++, которую вы уже знаете. C ++ 11, как и любой другой язык программирования, состоит из функций. Многие из них были там раньше, некоторые из них являются новыми. Но на самом деле ваш вопрос заключается в том, стоит ли мне изучать все возможности языка (в данном случае C ++ 11) или знакомиться только с 90% его?

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

С другой стороны, если вы ранее баловались написанием кода библиотеки / ядра, имитирующего некоторые функции STL / Boost, и обнаружили, что вы ограничены языком, потому что вы на 95% пришли к очень крутому, элегантному решению, но потом вас остановили, потому что вы узнали, что язык просто не поддерживает то, что вы хотите, вы поймете действительно потрясающую силу C ++ 11. С тех пор, как наша команда обновилась до VS2010 (и мы обнаружили Boost в процессе), я смог запустить какой-то сумасшедший потрясающий код, который будет просто невозможен до таких вещей, как ссылки на r-значение и пересылка параметров шаблона.

Также такие вещи, как лямбда, могут выглядеть чуждо, но они не вводят новую конструкцию. Вместо этого они значительно облегчают написание того, что мы имели раньше. Ранее каждая лямбда-функция должна была быть отдельным классом. Теперь это просто {... code ...}. Любить это.

Ключ в том, чтобы не смотреть на эти функции и не думать о том, насколько сложен этот список. Вместо этого используйте C ++, как обычно, и когда вы столкнетесь с некоторым сценарием, в котором эти новые функции C ++ 11 пригодятся (более 90% людей никогда не достигнут этого), вы будете очень рады, что расширение чтобы язык был сделан. На данный момент, я бы посоветовал вам просто достаточно узнать о языке, чтобы знать, что там, а не обязательно, как использовать все это.

DXM
источник
7
@ Shahbaz - я думаю, что вы все еще не понимаете, почему были добавлены безымянные функции. И «использование переменных без принятия их в качестве входных данных» называется закрытием и доступно во многих других языках высокого уровня. Если бы вы написали много шаблонного кода с объектами функторов, в C ++ 11 вы бы приветствовали лямбда-функции с распростертыми объятиями. Подумайте об этом так ... когда компилятор генерирует машинный код, нет такой вещи, как функция шаблона или класс. Все они «созданы» для создания конкретных классов / функций до этого момента. Лямбды - это то же самое, когда дело доходит до состояния ...
ДХМ
5
... функторы. Вместо того, чтобы люди писали тонну кода, по одному для каждого типа функтора и каждого элемента замыкания, который вы хотите передать, C ++ 11 позволяет вам указать синтаксис ярлыка и автоматически создавать экземпляр всего внутреннего класса функтора, как это создает шаблоны. Опять же, имейте в виду, что большинство из этих функций не будут использоваться в 98% кода уровня приложения, но они были добавлены, чтобы сделать такие библиотеки, как STL / Boost, гораздо более мощными и более простыми в реализации / обслуживании / отладке
DXM
10
@ Shahbaz: Хорошо, вы не понимаете лямбда-функции или замыкания. Это разумно. Тот факт, что они используются на разных языках, должен указывать на их полезность независимо от того, понимаете ли вы их или нет, и что вы должны понимать их, прежде чем критиковать их слишком сильно.
Дэвид Торнли
8
@ Shahbaz: Если вы думаете, что замыкания похожи на глобальные переменные, вы не понимаете замыкания. (Подсказка: глобальные переменные вызывают проблемы, потому что любая функция может их изменить.) Если бы вы понимали концепцию лямбда-выражений, а не реализацию, вы бы не приписывали это путанице классов и кода. Все в стандарте C ++ существует по причинам, которые были убедительны для большого количества умных людей. Вы не должны соглашаться с причинами, но не зная их, вы критикуете из-за невежества.
Дэвид Торнли
6
@ Shahbaz, нет абсолютно никакого сходства между замыканиями и глобалами, вы полностью упускаете суть. Прочитайте это: en.wikipedia.org/wiki/Lambda_calculus и взорвать свой мозг: en.wikipedia.org/wiki/Combinatory_logic
SK-logic
18

Разве так сложно написать функцию, что вы должны написать содержимое функции, встроенное в код, помимо того, что оно не имеет имени?

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

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

Херб Саттер говорит о лямбдах, может быть, он сможет убедить вас лучше:

http://channel9.msdn.com/events/PDC/PDC10/FT13

Ну, почему бы вам просто не написать код вместо того, чтобы делать его лямбда-функцией?

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

#define добавление_func (x, y) ((x) + (y))

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

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

Я согласен, это безобразно. Однако я помню, что говорил: «Какого черта я должен определить тип этого выражения, даже если компилятор может это определить?» во многих случаях. Это может сильно помочь в эти моменты.

Подводить итоги:

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

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

громко и ясно
источник
Аргументы о самодокументировании и меньшем количестве прокрутки и т. Д. Я уверен, что когда-то использовались противоположные аргументы, такие как «загроможденный код», «ограничение доступа» и т. Д., Чтобы аргументировать, почему функции вне класса должны быть запрещены. Я думаю, что люди должны стать более опытными, чтобы решить, что лучше. Мне кажется, это либо неудачный эксперимент, либо плохой дизайн. Я больше убежден, что не буду лабораторной крысой в этом эксперименте.
Шахбаз
О синтаксисе глядя некрасиво, взять эти два, например: bool is_alive;и bool thisSpecialObjectOfMineIsAlive;. Оба делают то же самое, но второй выглядит действительно безобразно. Зачем? Потому что я ошибочно подумал, что размещение большего количества информации делает это более ясным, но оно сделало обратное. Здесь то же самое, Страуструп имел в виду хорошее, предоставляя нам функции, но он просто не выглядел хорошо. Для меня это показывает плохой дизайн.
Шахбаз
3
хорошо выглядит = хорошо, а плохо выглядит = плохо.
DeadMG
@Shahbaz: Я думаю, что лямбды - это отличная концепция (и она существует уже много лет на таких языках, как Лисп). Я часто их использую в Хаскеле. Я менее уверен, что они вписываются в такие языки, как C ++, Java и т. Д. Они кажутся мне запоздалой мыслью: то, что было добавлено позже, потому что лямбды стали популярными. Почему они не были введены в эти языки с самого начала? Разве Страуструп и Гослин никогда не слышали о Лиспе?
Джорджио
8

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

Иногда бывает так, что после введения новой функции, старая больше не нужна, или она чувствует себя в противоречии с ней. «Чистый» язык должен быть самосогласованным, как он есть, и больше не нужно удалять нужные функции.

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

Вы должны изучить все это? Да, потому что все функции - хорошие или плохие, рано или поздно - используются. Хорошая ли это вещь для «качества» языка (признавая, что для него существует объективная мера) - это другая история: как долго должна сохраняться обратная совместимость? Трудно найти ответ, когда кто-то скажет 3 года, а кто-то скажет 50.

Альтернатива для сохранения C ++ более «регулярной» состоит в том, чтобы ... ломать ее чаще, с нуля. Но это больше не будет C ++.

Есть попытки сделать это также (например, подумайте о D: гораздо более ортогональны, чем C ++ (даже 11) на самом деле), но насколько они популярны? Одной из причин того, что их сложно получить импульс, является несовместимость со многими существующими кодами, которые еще должны выполняться.

Для меня C ++ 11 - это явно компромисс между новыми потребностями и обратной совместимостью. Это привело к некоторому «беспорядку» его спецификаций и реализации. Пока цена этого "беспорядка" не станет меньше стоимости несовместимости ... вы должны оставить этот компромисс.

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

Эмилио Гаравалья
источник
Я тоже согласен. И как разработчик я нахожу очень неприятным иметь постоянно меняющийся язык (который я должен изучать снова и снова). Если вы разрабатываете новый язык, вы должны начать все заново и использовать другое имя. Если вы хотите, чтобы он сотрудничал с устаревшим кодом, для этого есть отдельная компиляция. Поэтому я действительно не понимаю политику смены существующего языка путем включения последних функций, которые стали модными. Как кто-то сказал: дальнейшее развитие не означает автоматически прогресс.
Джорджио
«C ++ просто не может быть упрощен в этом смысле. Не в этом возрасте.»: Почему тогда другие языки программирования (например, C, Ada, ...) не следуют по тому же пути? Возможно, потому что у них есть своя ниша приложений, и ожидается, что они не будут инструментом для всех возможных областей применения.
Джорджио
@ Джорджио: да ... вы, вероятно, правы в "прагматическом" смысле. Но в теории ... Я помню несколько хороших дней, когда Паскаль был "обучающим языком ссылок", а Ада был "любителем языка программирования всего".
Эмилио Гаравалья
Я также изучил программирование на Паскале. Насколько я знаю, Ада прошла несколько ревизий, но базовый дизайн языка не был подорван. То же самое с Си и Паскалем. Если кто-то хочет разработать действительно новый язык, он должен быть достаточно смелым, чтобы сделать четкий шаг и начать что-то новое, например D, Java, C #. Моя проблема с текущим путем C ++ заключается в том, что он (излишне) становится слишком сложным. Если принципы KISS и YAGNI применимы к проектированию программного обеспечения, то почему они не должны также применяться к проектированию языка программирования?
Джорджио
@ Джорджио: о ... они применяются ... именно так, как вы сказали. Если вы думаете, что C # или D сделали лучший выбор, чем «вскипящий» C ++ (моя интерпретация ваших чувств), просто используйте их вместо C ++. Как время движется на C ++ будет медленно умирать. Прямо сейчас я вижу, что C ++ 11 дает новый шанс «вареному» C ++ 03, а D все еще чего-то не хватает, чтобы преодолеть стартовый барьер. Интересы экономики и корпораций также играют роль в финансировании и поощрении развития. Вы правы в теории, но реальный мир более сложен.
Эмилио Гаравалья
7

Даже если вы решите игнорировать новые функции C ++ 11, вы все равно получите от них пользу, потому что стандартная библиотека C ++ будет их использовать. Например, в C ++ 98 наличие переменной типа vector<string>могло привести к снижению производительности из-за количества копий, которое необходимо было сделать при увеличении вектора. С C ++ 11 конструктор перемещения это не проблема. На самом деле, я бы хотел, чтобы в C ++ 11 появилось больше новых функций, а не меньше, особенно в стандартной библиотеке.

Неманья Трифунович
источник
6

По прошествии стольких лет все еще много людей изучают и пишут код на C. Почему? Потому что язык хороший.

Во-первых, большинство студентов в наши дни изучают Java или .NET, а не C. Во-вторых, люди все еще используют C не только из-за его преимуществ в качестве языка, но в основном потому, что существует огромное количество существующих программ, написанных на C, которые нуждаются поддерживаться и расширяться, и потому что во многих случаях (например, встроенные платформы) компилятор C - это все, что есть. Между прочим, это некоторые из причин, почему люди все еще пишут COBOL.

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

Дима
источник
Вы процитировали мое предложение не полностью. Как я уже сказал в предложении после, goodозначает, что он следует правилам хорошего дизайна языка программирования. Я не знаю, где вы учитесь, но я знаю 4 или 5 стран, и все они начинают изучать программирование на C. Как я уже говорил, в C нет почти никаких исключений (что-то противоположное в Java, вы вряд ли могли бы найти конструкцию, которая не имеет исключения).
Шахбаз
1
@ Shahbaz: я процитировал полные предложения. Вы установили причинную связь, и я сказал, что она в лучшем случае неполная. К счастью, я больше не учусь. :) Я сделал достаточно этого. Я живу в США, и когда я поступил в колледж (более 15 лет назад), C был вводным языком. Однако сегодня большинство американских школ начинаются с Java, и не так много молодых программистов, которые знают C.
Дима
5
@ Shahbaz: я действительно не вижу проблемы с языковыми правилами, имеющими исключения. Да, C намного проще, чем C ++. С другой стороны, C ++ облегчает написание более простого кода. Чтобы написать более простой код, вам нужно больше возможностей языка. Это делает язык более сложным. Мне, например, нравятся такие вещи, как классы, ссылки, RAII, шаблоны, конструкторы, деструкторы, исключения и пространства имен. Но вы сказали, что ваш вопрос не о C против C ++, поэтому я не написал об этом в ответе.
Дима
5
  • Сборка была создана потому, что людям не нравилось писать машинный код
  • C был создан потому, что людям не нравилось писать ассемблер
  • C ++ был создан потому, что людям не нравилось писать C
  • C ++ 11 был создан потому, что людям не нравилось писать C ++

В вашей карьере в C ++ вы достигнете точки, когда вы скажете себе: «Я бы хотел, чтобы функторы были проще» или «Почему NULL - int?» и тогда вы поймете C ++ 11.

Pubby
источник
Все языки были созданы потому, что кому-то не понравились существующие. Это не делает никого из них хорошим.
Шахбаз
Я не говорю, NULLдолжен быть int. Это не должно Что я не считаю правильным, так это ввести конструкцию на языке, которая решает эту проблему, но вводит исключения. Они должны были быть в состоянии сделать то же самое лучше.
Шахбаз
2
«C ++ 11 был создан потому, что людям не нравилось писать C ++»: если им не нравилось писать C ++, почему C ++ является подмножеством C ++ 11?
Джорджио
1
Должно быть: C # и Java были созданы потому, что людям не нравилось писать C ++.
Кальмариус
4

Обучение всегда полезно. Знание - сила.

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

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

И , как я заметил , - реальная забота не поэтому учиться, но зачем использовать . И это совершенно другой вопрос.

littleadv
источник
4

Вы должны изучить C ++ 11, потому что добавленные функции позволяют писать лучший код. Некоторые люди упоминали о безопасности типов указателей NULL и лямбд, которые очень хороши. Но я хочу обратить внимание на то, что я считаю самым драматическим изменением в C ++ 11, особенно в большой производственной среде: семантика перемещения.

C ++ 11 поддерживает отдельные понятия «перемещение» и «копирование». В обычном C ++ у нас просто есть оператор =, который в основном выполняет оба этих действия. Но на самом деле мы выражаем две разные идеи с одним оператором, что опасно.

Самый очевидный пример того, где это полезно, это новый unique_ptr. Он обладает всеми лучшими функциями старых auto_ptr и scoped_ptr. Предположим, мы хотим иметь указатель, который гарантированно будет единственным указателем, указывающим на объект. Как мы имеем дело с a = b? Ну, раньше мы застряли, вы можете либо полностью запретить это (как scoped_ptr), либо мы могли бы делать то, что делает auto_ptr, когда a = b крадет владение у b. Такое поведение auto_ptr очень запутанно, потому что a = b на самом деле меняет b. unique_ptr обрабатывает это: a = b не допускается, но у вас есть a = std :: move (b) для кражи владения. Чем это полезно? Где есть отдельная (перегруженная) версия подкачки, в которой используется семантика перемещения, а не копирование семантики. Это означает, что этот unique_ptr можно поменять местами, без проблем. Это означает, что unique_ptr, в отличие от auto_ptr, безопасно использовать в контейнере, а затем сказать, сортировать. unique_ptr - это, по сути, все и безопасное управление памятью, когда вам не нужно несколько указателей на один и тот же объект.

Другой замечательный пример: предположим, у вас есть объект, который нельзя скопировать. Это полезно в ряде ситуаций. Вы никогда не сможете вернуть этот объект из функции, потому что когда функция завершается, она копирует все, что вы возвращаете. Ирония в том, что обычно компилятор на самом деле оптимизирует это (то есть, в конце ничего не копируется, возвращаемое значение создается по адресу возможного присваивания). Но это не имеет ничего общего с тем, почему мы сделали его не копируемым; возвращение из функции - это на самом деле просто перемещение объекта изнутри области действия функции наружу. Теперь вы можете писать объекты, которые нельзя скопировать, но которые можно перемещать, и эти объекты можно возвращать из функций.

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

Нир Фридман
источник
А также, кстати, эффективный.
Нир Фридман,