На что я могу рассчитывать при переходе с C и C# на C++?

Вот простой вопрос.

Я проделал много работы, используя как C, так и C# (2.0), но никогда ничего не использовал на C++. Что я могу ожидать от других при изучении C++? Будут ли какие-то серьезные препятствия, на которые я тоже должен обратить внимание? Есть ли у кого-нибудь хорошие рекомендации по ускоренному курсу / веб-сайту для изучения C++ для опытного программиста?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
484
14

Ответы 14

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

он исходит из фона C, в C++ меньше управления памятью, не больше.

gbjbaanb 24.12.2008 18:11

Хммм ... Крутой. Если вас устраивает .NET и указатели, не должно быть слишком много нового.

Я думаю, что работа с заголовочными файлами C++ будет интересной. Также есть C++ STL, с которым можно познакомиться.

Возможно, вам также придется иметь дело с людьми, кричащими вам о таких вещах, как множественное наследование.

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

Я настоятельно рекомендую: «Эффективный C++ и более эффективный C++». И если вы в этом заинтересованы, "Эффективный STL" может вам помочь :)

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

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

удачи :)

Что ж, я использую C++ уже более 10 лет, поэтому мой ответ был бы: изучение строгого управления памятью, шаблоны C++, STL, а затем Boost. Это должно занять у вас несколько месяцев, а затем, скажем, 5 лет :)

Из книг мне нравятся Exceptional C++ Херба Саттера и More Exceptional C++.

Хм ... каждый день узнаешь что-то новое. Какие аспекты управления памятью являются новыми в C++ по сравнению с обычным C? У меня создалось впечатление, что все гадости уже написаны на C.

biozinc 24.12.2008 15:44

Для начала вы используете new / delete, в отличие от malloc / free, затем у вас есть перегрузка new / delete, затем у вас есть распределители экземпляров, распределители классов, умные указатели в изобилии, чтобы назвать несколько очевидных.

Robert Gould 24.12.2008 15:50

Спасибо! Теперь я знаю, на что нужно обратить внимание, когда вернусь к C++.

biozinc 24.12.2008 15:57

Вы правы, неприятные вещи уже есть в C. Довольно ошибочно говорить программисту на C, что «В C++ вам нужно научиться управлению памятью». C++ просто добавляет различные способы обертывания выделения памяти.

jalf 24.12.2008 17:06

Вот некоторые с моей точки зрения:

  • Указатели играет большую роль в C++. В C# у вас есть только ссылка типы. И у вас может заболеть голова от ошибка указателя.
  • Вы также должны управлять выделение памяти вручную. А также есть шанс, что ваша программа возникнет утечка памяти, если это сделано не правильно. В C# каждый объект утилизируется сборщиком мусора, автоматически.
  • Декларации и определения классы обычно разделяются на заголовочный файл (.h) и исходный файл (.cpp или .cc). Это вызовет сначала небольшая путаница.
  • У вас не будет так много базовых классов поддержка библиотек в C++ как в C#. Для Например, у вас не будет Класс HttpRequest, встроенный в C++.
  • Следовательно, вам придется использовать много внешних библиотек и знаю как работать с .dll или .lib.
  • В C++ нет Interface, как в C#. Ты будет использовать абстрактный класс (и множественное наследование).
  • строка в C++ представляет собой массив символов или указатель на char.
  • Есть некоторый алгоритм и данные структура, доступная для использования в Стандартная библиотека шаблонов (STL.) Но нужно время, чтобы научиться, прежде чем ты можно начать эффективно использовать :)

Вы также можете изучить C++ / CLI, чтобы смешивать код .NET и собственный C++ вместе, чтобы получить лучшее из обоих миров.

Если он раньше работал с C, то указатели и управление памятью преподнесут несколько сюрпризов.

jalf 24.12.2008 17:05

Я категорически не согласен с пунктами 1 и 2. В современном C++ вы никогда не используете delete и редко используете new. Управление памятью осуществляется через RAII. Я испытал утечки памяти более в C#, чем в C++ на самом деле.

Alexandre C. 16.08.2011 14:57

@Alexandre По общему признанию, в то время я не знал о некоторых лучших практиках современного C++. Теперь, когда я видел все больше и больше утечек памяти в приложениях C# и C++, я знаю, что их одинаково сложно отследить :(

Gant 16.08.2011 19:36

Что касается различий в реализации языка - и я думаю, что вам нужно быть осторожным с такими вещами, как управление памятью, объявления в заголовках и т. д. - я думаю, что сложнее всего иметь дело с дополнительной перегрузкой специальных символов в синтаксис. После многих лет написания кода на C# я больше всего спотыкаюсь о лишних *, & и <>. Моя первая реакция заключается в том, что код C++ очень похож на большое регулярное выражение.

Я уверен, что после того, как вы его некоторое время использовали, это исчезнет, ​​но я больше не делаю достаточно C++, чтобы чувствовать себя комфортно, потому что я точно знаю, какой символ использовать в каждом случае - я передаю указатель или ссылка на этот объект?

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

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

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

Однако мне нравятся возможности C++ по созданию шаблонов. Когда-нибудь C# расширит эту технику.

Почему вы не используете исключения C++?

Rob 24.12.2008 16:51

Собственная обработка исключений C++ не так мощна, как в CLR. Я не нашел в этом особого применения, так как привык генерировать исключения способом CLR.

spoulson 29.12.2008 16:40
  1. Управление памятью
  2. Более сложный синтаксис
  3. Управление памятью
  4. Меньше инструментальной поддержки, чем C#, на протяжении всего жизненного цикла ООП.
  5. Управление памятью

И я уже говорил об управлении памятью?

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

Я вижу, как несколько человек указывают на управление памятью как на большую проблему, потому что вам придется делать это вручную. Что ж, не верьте им, это неправильно. Если вы не находитесь в экзотической / старомодной среде, в C++ есть инструменты, которые помогают нам управлять памятью (а также любыми другими ресурсами) неявно и детерминированно. См. Boost / std :: tr1 shared_ptr <> и RAII.

Большая разница с памятью, собираемой сборщиком мусора: вам придется позаботиться о циклах самостоятельно.

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

Я должен согласиться с сообщением фез: Ускоренный C++ необходимо прочитать, если вы хотите научить вас, как можно (/ нужно?) Использовать C++.

Циклические ссылки между классами [в C++]. ООП в C++ действительно наполовину готов, если вы спросите меня.

edit: Хорошо, я полагаю, что некоторые подробности в порядке. Скажите, что у вас есть: класс Foo и класс Blah. Класс Blah ссылается на класс Foo, класс Foo ссылается на класс Blah. Предположим, вы идете по наивному пути, вы можете реализовать его следующим образом:

#include <blah.h>
class Foo {
    Blah blah;
    ...
}

и Бла:

#include <foo.h>
class Blah {
     Foo foo;
     ...
}

Это, вероятно, не сработает. Вместо этого вам нужно использовать прямые ссылки, то есть Foo становится:

class Blah;

class Foo {
    Blah blah;
    ...
}

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

Не уверен, почему вы думаете, что C# не может иметь циклических ссылок. Излишне говорить, что вы ошибаетесь (blogs.msdn.com/nickmalik/archive/2005/03/18/398601.aspx).

Matthew Flaschen 26.12.2008 14:44

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

wds 08.01.2009 17:43

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

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

В C++ многие конструкции C, хотя и законные, в основном избегаются:

  • Необработанные указатели (обычно заменены интеллектуальными указателями, такими как boost::shared_ptr или std::auto_ptr, или ссылками
  • Распределение памяти в пользовательском коде (обычно должно быть заключено в интеллектуальный указатель или в специально созданный объект RAII)
  • Указатели на функции (обычно заменяются функторами для повышения безопасности типов и производительности)
  • goto (часто используется в C для перехода к коду очистки. Опять же, RAII делает ненужным)
  • препроцессор (практически никогда не требуется. Вместо этого лучше использовать шаблоны)

Конечно, для каждого из этих пунктов есть исключения, но, как правило, код C++, в отличие от кода C, почти полностью исключает их использование.

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

  • Конструктор (как в C#, который инициализирует класс с нуля)
  • Конструктор копирования (инициализирует класс как копию другого объекта)
  • Оператор присваивания (поскольку классы - это то, что C# будет рассматривать как типы значений. И поэтому присваивание - это не просто изменение ссылки, но и копирование всего содержимого объекта определенным пользователем способом)
  • Деструктор

Деструктор, вероятно, является наиболее важным понятием в C++. Это жизненно важно для RAII, так как это способ управления памятью или другими ресурсами, потому что он автоматически вызывается, когда объект выходит за пределы области видимости. Это позволяет вашим классам давать множество гарантий, которых невозможно достичь на C или C#. Например, boost :: thread предоставляет ограниченные блокировки, которые гарантированно снимаются, когда выходит за пределы области видимости, независимо от того, возвращается ли функция нормально, генерируется исключение или что-то еще. Поэтому при использовании этой библиотеки пользователю не нужно беспокоиться о снятии блокировок или других ресурсов. Это происходит автоматически, как только вы закончите с ними.

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

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

Джалф совершенно прав - имея опыт работы с C / C#, вы практически уже знаете весь базовый C++, который вам нужен, и вы также знаете ООП, так что вы так же хороши, как и сделали.

Однако есть 2 вещи, которые будут для вас новыми:

  • RAII: это позволяет вам автоматически управлять памятью, вам больше не нужно помнить о том, чтобы освободить все, что вы заблокировали. Круто, да! Это также помогает с любым другим ресурсом, вам больше не нужно помнить о закрытии этого сокета, файла, соединения с БД - RAII сделает это за вас. Ни в C, ни в C# этого нет.

  • STL / Boost: это «библиотека классов C++», полная полезных утилит и битов. Все стандартные контейнеры находятся в STL (например, «словари», «массивы» и «списки») вместе с алгоритмами, которые вы можете применить к ним (например, если у вас есть список элементов данных, вы можете предоставить небольшой функциональный объект (называемый функтор), а затем передать оба в общий алгоритм. Это действительно мощный инструмент, с его помощью можно проделать массу работы).

Основное отличие состоит в том, что C++ основан на значениях, а C# - на ссылках.

В C#, когда вы передаете объект методу, вы фактически просто передаете ссылку, поэтому вызывающий метод и вызываемый метод смотрят на один и тот же объект.

В C++, когда вы передаете объект методу, создается копия этого объекта, и вся копия передается методу. Изменения, внесенные вызываемым методом в копию, не влияют на оригинал в вызывающем методе. Эталонное поведение можно смоделировать на C++, используя эталонный синтаксис:

void somemethod(someclass& obj);

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

David Rodríguez - dribeas 25.12.2008 13:43

Я не уверен, почему вы называете & ссылки симуляцией, поскольку они являются ключевой и оригинальной особенностью C++, а не каким-то неясным расширением.

Matthew Flaschen 26.12.2008 14:41

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

James Curran 31.12.2008 20:07

Другие вопросы по теме