2010-03-30 2 views
4

Мне нужно изучить C++, чтобы научиться создавать приложения Nokia WRT и maemo. Мне нужно знать, что такое gotchas и какой аспект C++, который мне нужен/должен узнать или больше сосредоточиться. Одна вещь, на мой взгляд, заключается в том, что у C++ нет сборщика мусора. Поэтому мне нужно сосредоточиться на переменном типе. Но есть ли другие, которые действительно важны, и я не могу игнорировать его?Что Gotchas при обучении C++, если я пришел из PHP/Java?

+1

Вы можете начать со списком ошибок, C++: http://stackoverflow.com/questions/30373/what-c-pitfalls-should-i-avoid –

+5

Я думаю, что C++ является гораздо более сложным (из-за отсутствия лучшего слова), чем PHP, и вы не просто изучаете различия между PHP/Java и C++ ... Вы изучаете C++. –

+0

да, я знаю, что я должен изучить C++. Может быть, моя формулировка неверна. Мне просто нужно знать, какую часть языка мне нужно сосредоточить, чтобы я мог сосредоточить свое время обучения на этом конкретном аспекте. – ariefbayu

ответ

13

Основная цель - попытаться представить C++ с точки зрения того, как он отличается от PHP или Java.

Извините, это просто не работает. C++ отличается от этих языков почти во всех важных аспектах, помимо синтаксиса для арифметики. Иногда различия тонкие. Вам нужно научиться новому, и не думать, что что-то, что подходит для PHP или Java, будет хорошо работать для вас на C++.

Тем не менее, общие трудности включают в себя:

  • управление ресурсами: RAII; реализация конструкторов копирования, деструкторов и operator=; избегая необходимости выполнения копий ctors, dtors, operator =.
  • понимание, какие ссылки, указатели, значения и автоматические переменные.
  • избегая неопределенного поведения (myarray[i] = i++; является излюбленным). PHP и Java являются более «жестко» определенными языками, чем C++: во-первых, поведение программы, скорее всего, будет определено и, следовательно, надежно. Из-за этого отдельные реализации более похожи, чем реализации C++. Сложно написать программу на C++, которая не только делает неправильную вещь, но и делает разные вещи на разных прогонах, включая сбой, развращение данных и т. Д.
  • обучение безопасному и эффективному использованию шаблонов, множественное наследование, перегрузка оператора и другие функции, с которыми вы не знакомы.
  • правильные идиомы для бросков и ловушек исключений (бросать по значению, ловить по ссылке, не выбрасывать из деструктора).
  • Письменный переносимый код (понимая разницу между стандартными гарантиями и тем, что не гарантируется, но что ваша реализация происходит), определяемое реализацией поведения, такое как размеры основных типов).
  • Стандартные библиотеки C++ ограничены по сравнению с Java или PHP. Вы также будете использовать нестандартные библиотеки. Например, Maemo использует GTK + и/или Qt. Часто ответ на вопрос «как я могу сделать X в C++»: «вы не можете сделать это, используя только стандартный C++, вам нужны API-интерфейсы платформы или переносимая библиотека, скомпилированная для вашей системы». X может представлять собой графику, сокеты, регулярные выражения, многопоточность, обработку XML, криптографию. Особенно с мобильных платформ вам нужно следить за версиями ОС, время от времени вещи могут и будут меняться под вас.
2

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

С другой стороны, вы получите то, что они называют «детерминированной финализацией». Огромная выгода. Посмотрите, как акроним, «RAII». Я думаю, что это, возможно, одна из самых важных идиом на C++.

Это означает, что «Инициализация ресурсов является инициализацией», но на самом деле это означает: «Когда этот деструктор срабатывает, я очищу вас после вас, даже при наличии исключений». На практике это означает, что любой объект, который вы создаете или открываете для закрытия или удаления, вы можете использовать с помощью интеллектуального указателя. Умный указатель очистится после вас. Это очень, очень мощно, как только вы это понимаете и начнете использовать его. Это делает вашу проверку ошибок, обработку исключений и код очистки ресурсов очень простыми.

+1

«Я думаю, что это, возможно, один из самых важных идиом в C++» - в то время как я беру другую точку зрения, что это неоспоримо является наиболее важным идиома в C++ ;-) –

3

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

Кроме того, если вы пишете специфический для платформы код (например, приложение Qt или Microsoft MFC), вы часто увидите примеры с использованием контейнеров, специфичных для конкретной среды, где STL будет более разумным выбором. STL (и Boost) могут заполнить пробелы. Использование графического интерфейса не означает, что вы должны использовать все, что предлагает инфраструктура. Держитесь подальше от нестандартных контейнеров, если вы не знаете без тени сомнения, что никогда не будете переносить программу или повторно использовать части кода.

1

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

void do_stuff(std::vector<int> my_array) 
{ 
    ... 
} 

то my_array, который передается в это скопируйте указанного аргумента. Копирование всего массива, как это дорого, поэтому в общем, вы хотите передать по константной-ссылке:

void do_stuff(const std::vector<int>& my_array) 
{ 
    ... 
} 

(Примечание: опускать const, если вы хотите изменить исходный my_array).

2

One gotcha Я видел, как некоторые программисты Java делают, когда переход на C++ является утечкой памяти «try-catch». Например:

try { 
    myType pVar = new myType(); 
    DoSomething(pVar); 
    delete pVar; 
} 
catch (exception) { 
    cout << "Doh! Something failed!" << endl; 
} 

В случае, описанном выше, если метод «DoSomething() бросает исключение, PVAR никогда не удаляются, так что будет утечка памяти

(Решения для этого включают. : объявляя все переменные перед блоками try/catch, используя auto_ptr, или просто избегая попыток try-catch для начала!)

1

Мне любопытно, почему «PHP/Java» здесь рассматривается как одна вещь. 't.

  • Переход на Java-> C++ довольно велик, но это выполнимо, вам просто нужно узнать много дополнительного синтаксиса, несколько дополнительных понятий, таких как деструкторы, конструкторы копирования, разбиение объектов и перегрузка операторов, а также прийти к соглашению с C++ библиотека.
  • С другой стороны, переход на PHP-> C++ на другой порядок больше, поскольку он относится к (а) очень плохо определенному исходному языку, (б) языку, основанному на шаблонах, а не на классе, и (c) язык, который выполняется в специальной среде.