Думая на С++?

Я использую язык программирования Java. Я перешел на С++, который был несколько скалистым. "Скалистость" не находится в процессе обучения, но больше по строкам "Мышление в С++".

Я видел, как многие люди говорят, что сначала вы должны научиться C (я технически это знаю), а затем я вижу, что люди говорят, что не пропускают C и идут прямо на С++. И снова это не проблема "обучения"; это проблема "мышления"; Я знаю синтаксис для С++, я знаю OOD в С++ и т.д.

Например, этот код в SDL я могу объяснить, как если бы я это знал, но я не могу "воспользоваться преимуществами" указателей:

SDL_Surface* hello = NULL;

Должен ли я программировать на C, чтобы "использовать" это? Что я должен делать, чтобы привыкнуть к указателям, если я никогда не использовал их, исходя из языка, такого как Java?

Ответы

Ответ 1

Должен ли я программировать на C, чтобы получить "используется" для этого?

Нет, не стоит. C был хорошим введением в С++, когда С++ в основном рассматривался как "C, но с классами". С++ развился так много от того мышления, что написание кода C на С++ делает очень очень плохой код на С++.

Что я должен делать, чтобы привыкнуть к если я их никогда не использовал исходя из языка, такого как Java?

Зная, как использовать указатели в С++, подразумевается несколько ключевых областей (и вы должны, вероятно, изучать их один за другим):

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

  • указывает на функции (эта часть также используется совместно с C).

  • литье указателей (static_cast, dynamic_cast,...). Эта часть является специфичной для С++. Вы также можете определить свой собственный тип броска и поэкспериментировать с ним немного (и посмотрите пример boost:: lexical_cast в качестве примера).

  • указывает на объекты-члены и функции-члены.

  • RAII для указателей и различных реализаций интеллектуальных указателей: циклически привязанные указатели, указатели с подсчетом ссылок (boost:: shared_ptr), уникальные указатели (std:: auto_ptr), указатели с областью.

  • указатели функций упаковки в классах функторов (см. std:: tr1:: function или boost:: function).

  • ссылки на объекты и то, как они похожи и в отличие от указателей; Где использовать ссылки и где использовать указатели.

  • сходства между указателями и итераторами.

  • используя operator* и operator->, чтобы имитировать поведение указателя для объекта (и если не злоупотреблять этим).

  • указатели и const ness/mutability: в чем разница между указателем, указателем const, указателем на значение const и указателем const на значение const (и когда использовать каждый), и аналогично использованию изменяемых указателей.

Текущая практика в совете С++ против использования указателей в вашем коде, если они не управляются автоматически вашим кодом (например, через RAII).

Ответ 2

Это правда, что указатели - это большое дело, и C и С++ разделяют эту концепцию.

Но С++ - это не просто C с объектами.

Есть две бесплатные книги, которые вы можете скачать из Planet PDF by Bruce Eckel под названием Мышление в С++ (тома я и II), которые действительно помогут вам понять смысл С++.

Многие С++ также являются инструментарием, будь то стандартная библиотека (std) или MFC или классы из библиотеки географов против зерен или что-то еще. Это тоже имеет значение.

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

Ответ 3

Если вы понимаете синтаксис, то единственным способом стать "свободным" на языке является его использование.

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

Указатели очень просты, как только вы их получите. Очень хорошая идея при использовании указателей - использовать префиксное обозначение "p" . Для каждого указателя (уровень косвенности) добавьте "p" в начало вашего имени переменной, чтобы напомнить вам, что это указатель:

Vehicle vehicle     = an actual vehicle
Vehicle *pVehicle   = a pointer to a Vehicle
Vehicle **ppVehicle = a pointer to a pointer to a Vehicle

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

vehicle.SetName("Ford Focus");       // Directly access an object instance
(*pVechicle).SetName("Ford Focus");  // Dereference once
(**ppVehicle).SetName("Ford Focus")  // Dereference twice

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

(*pVehicle).DoSomething()
pVehicle->DoSomething()
pVehicle[0].DoSomething()

Когда вы используете арифметику по указателям, они работают в единицах транспортного средства, а не в байтах, i.e

pVehicle++;   // Move to the next vehicle record, not just the next byte

И, наконец, для каждого

pVehicle = new Vehicle

вам нужно сбалансировать свой код с помощью:

delete pVehicle;
pVehicle = NULL;

(edit) О, и почти забыл самый важный: ВСЕГДА проверяйте, что ваш указатель действителен, прежде чем пытаться его использовать!

if (pVehicle != NULL)
    ...use pVehicle

Я нахожу нотацию "p" неоценимой, так как вы никогда не забудете, что что-то является указателем, а число p указывает вам, сколько разменований требуется. После того, как я его усыновил, я прекратил писать ошибки NULL для разыменования/доступа.

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

Ответ 4

Я не думаю, что обучение C поможет с вашим "мышлением" в С++ ". Как правило, вам просто нужно привыкнуть к некоторым концепциям С++ и почему они полезны.

Ключевыми являются умные указатели (более обычно RAII) и огромные шаблоны.

Также имейте в виду, что С++ является языком multi-paradigm, а не строго ООП. Часто лучшее решение не совсем объектно ориентировано (STL - отличный пример лучшего дизайна шаблонов, чем основанный на объекте).

Ответ 5

Вы знаете, есть очень хорошо расцененная книга, которая на самом деле озаглавлена ​​ "" Мышление в С++":) Еще лучше, это бесплатно! Это должно помочь вам перебирать вещи, как указатели, на более глубоком уровне - это явно предназначено для этого.

Ответ 6

Язык программирования - это всего лишь инструмент. Суть в том, что чем больше вы знаете, тем лучше. C - очень хороший язык для изучения ИМО, по тем же причинам упоминается один из соучредителей (Joel Spolsky): http://www.joelonsoftware.com/articles/CollegeAdvice.html. Я прочитал эту статью до того, как окончил школу, и дал понять, что я должен посоветоваться с ней, прежде чем закончить учебу.

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

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

Наконец, моя степень фактически не требовала, чтобы я взял курс компиляторов. Я мог бы уклониться от него, но поскольку это один из самых печально известных классов, я чувствовал, что буду меньше, если я не возьму его. Я сделал ужасный класс мудрый, но я узнал так много важных вещей в этом классе, что это был достойный пресловутый рок, который я связал с моим GPA, взяв его. Если вы узнаете, как на самом деле реализован язык программирования, у вас есть огромное преимущество, а только знание того, как работать с "языком X". Любой язык программирования требует времени для изучения, даже если у вас есть все основы в мире. Случайные толчки повсюду будут пытаться рассказать вам, как легко учиться "языку X", но эти люди обычно просто не уверены и хотят, чтобы они чувствовали себя хорошо, действуя так, как будто они родились с возможностью программирования в "языке X", когда действительно, они только что поставили часы, чтобы узнать это. Никто не рождается, зная это, просто дайте себе время, чтобы учиться, но будьте умны. Разработайте систематический метод изучения нового языка (моя стратегия всегда начинается с написания "привет мир" на этом языке), и вы сделаете все возможное. КОНЕЦ RANT.

Ответ 7

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

У моей подруги были проблемы с указателями при запуске на С++, и она рекомендует книгу под названием Понимание указателей в C.

Что делать с указателями, которые относятся к "мышлению на С++"?

  • Указатели могут быть установлены в NULL (т.е. 0). Это может быть невероятно полезно для моделирования ситуаций, в которых вы можете иметь значение.
  • Указатели могут быть перенаправлены на новые объекты – в отличие от, скажем, ссылок, которые только инициализируются и не могут быть повторно назначены после инициализации.
  • Указатели могут быть неявно повышены (от производных классов до базовых классов).
  • Указатели могут быть явно опущены от базовых классов к производным классам. Вы можете сделать это с помощью static_cast , если, чтобы узнать, что такое производный класс! Обычно люди делают это с помощью dynamic_cast для дополнительной проверки работоспособности во время выполнения.
  • Указатели могут быть переведены в и из void*, если вы хотите передать указатель кому-то, но вы не хотите, чтобы они знали тип объекта, на который вы указываете. Другими словами, указатели могут быть непрозрачными.
  • Указатели и массивы почти эквивалентны.

Вот некоторые вещи, связанные с указателями, которые уникальны для С++ и C:

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

Ответ 8

По-моему, С++ как язык настолько сложный, что его понимание все еще развивается. Я все еще открываю новые методы программирования. И C больше не является хорошим введением в С++. На самом деле, слишком сильно погрузившись в C, вы научите вас плохим привычкам С++ и будете стремиться ослепить вас к некоторым из действительно полезных вещей на С++. Например, в С++ я считаю, что указатели важнее, чем в Java, но не так сильно, как в C.

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

Вот мой личный список важных идей на С++, с которыми вам следует практиковаться и привыкнуть:

  • Используя swap (и в С++ 0x конструктор перемещения и оператор присваивания), чтобы написать код с надежной гарантией.
  • Метапрограммирование шаблонов (шаблоны - это в основном функциональный язык внутри С++, который выводит программу на С++).
  • RAI idiom (RAII означает инициализацию ресурсов) - это что-то в С++, которое принципиально отличается от Java, и очень важно понимать.
  • И, связанный с RAII, понятие о том, что объекты не-примитивных типов обычно создаются без использования new. Вы создаете объекты непосредственно в стеке или ссылаетесь на них по включению, а не по ссылке. Это огромное, но тонкое отличие от Java.
  • Итераторы - то, что не-Javaesque использование указателей превратилось в основном
  • И действительно, указатели, которые не используются как итераторы, точно такие же, как переменные не-примитивных типов (т.е. материал, полученный из Object) в Java, за исключением отсутствия сбора мусора.

Ответ 9

У этого вопроса нет ничего общего с мышлением в С++. Вам просто нужно узнать больше С++. Хорошо, что вы уже знаете Java, потому что почти все, что важно в Java, прямо присутствует в (и действительно заимствовано из С++ или зависит от него), поэтому вам просто нужно узнать больше о С++, чтобы научиться "отображать" эти идеи Java-дизайна в С++.

Не изучайте C для изучения С++. Это глупый миф. Это два разных языка. Изучите С++ для изучения С++.

Ответ 10

Если вы действительно думаете о концепции мастеринга указателей, я предлагаю эту книгу:

Понимание указателей в C по Yeshwant Kanitkar.

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

Ответ 11

Если вы уже ежедневно работаете над проектом на С++, скорее всего, вы уже привыкли к использованию указателей. Потребуется больше времени для того, чтобы знания и повторяющиеся шаблоны утонули. (Если я помню, что правильный знаменитый гуру С++ говорит, что для получения продуктивности требуется от 6 месяцев до года.)

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

Чтобы эхо Эван Думая на С++?, С++ - это язык с несколькими парадигмами. Думать в С++ в основном о мышлении в парадигмах. Например, libtiff полностью основан на указателях функций, а COM полностью посвящен OOP, используя только указатели, vtables и подсчет ссылок. MFC обертывает много вещей в макросы и таблицы.

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

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