Есть уже много хороших ответов. Мой будет более «ориентированным на образ мышления».
В то время как« Данные должны вести себя »можно сделать на C (и это сделано!), в C ++ все необходимое для простой реализации уже доступно: инкапсуляция, конструкторы, переопределение перегрузки, шаблоны и т. д. ..
Я считаю, что эта идея «Данные должны вести себя» - очень хороший руководящий принцип при кодировании на C ++.
Вы найдете множество функций C ++, которые можно реализовать в C, и некоторые люди используют его как предлог, чтобы не изучать их. Этот образ мышления опасен (это часть " ВЫ должны стать лучшим. Если вы пишете код C ++, то пишите его способом C ++.
Определение типа ваших структур, чтобы сделать их компилируемыми компилятором C, - плохая шутка. Использование указателей вместо ссылок - это пощечина вашему будущему. extern «C»
только сделает ваш код слабее, но не сильнее. А использование void *
для универсальности только увеличит количество других программистов C ++, которые с радостью заплатят за то, чтобы вам удалили голову впечатляюще болезненным способом.
Никогда не пытайтесь писать C-совместимый код. если только вам действительно действительно не придется.
Вы просто утяжелите себя трудоемким стилем кодирования для функции, которую никогда не будете использовать.
Работа на низком уровне имеет странные последствия для некоторых разработчиков. Они очень верят в свой контроль над скомпилированным кодом. Им сложно делегировать этот контроль конструкциям более высокого уровня.
Хорошим примером этого является отказ от шаблона конструктор / деструктор, потому что « иногда конструкторы занимают слишком много времени ... Лучше сделать это по-моему. .. ".
Компилятор C ++ вполне может оптимизировать явно неоптимизированный код. Фактически, код, созданный компилятором, может сильно отличаться от того, который, по вашему мнению, вы создали.
Не пытайтесь быть лучше / умнее, чем компилятор, потому что:
Так что доверяйте своему компилятору.
Не контролируйте создание своего кода на микроуровне. Делайте свою работу и позвольте компилятору делать свое собственное.
Обратите внимание, что этот момент не должен использоваться для оправдания создания медленного / неэффективного кода. Если преждевременная оптимизация является корнем всех зол, вы все равно должны использовать свои знания языка и компилятора для создания хорошего и эффективного кода (см. Следующий пункт).
Например, тот факт, что виртуальные методы добавляют одно косвенное указание к вызову функции, для некоторых людей означает, что производительность резко снизится. По правде говоря, проблемы с производительностью часто возникают где-то еще.
Незнание не является оправданием.
Знать код, созданный для каждой конструкции C ++ (т.е. встраивание, ссылки, конструктор, деструктор, исключение, перегрузка функции, переопределение функции, шаблон, виртуальная функция , так далее.). Знайте, что будет оптимизировано, а что нет.
Таким образом, вы не только не будете платить за то, что вам не нужно (это руководящий принцип C ++), но и получите прибыль от того, что стоит ноль, но приносит много.
Есть люди, которые проводят исследования на C ++, которые в день своего рождения были лучше, чем большинство из нас когда-либо будут. Даже если мы проигнорируем Страуструп , такие имена, как Meyers , Абрахамс , Александреску , Саттер и т. Д. Регулярно возникают вместе с новыми идеями. Несмотря на (или как следствие) его инопланетный взгляд, STL является революционной библиотекой. А такая библиотека, как Boost , несмотря на ее «небольшой размер» по сравнению с некоторыми законченными фреймворками (такими как Java или .NET API), представляет собой огромное хранилище отличного кода, предлагаемого вам для изучения.
Просто потому что вы находите какую-то новую функцию «странной» или «чужой», не стоит ее недооценивать. Попытка понять это, ВОЗМОЖНО, даст вам еще один инструмент в вашем распоряжении, и ВСЕГДА улучшит ваше владение языком, и ВСЕГДА заставит ваш мозг работать, что хорошо в бизнесе разработчиков.
Большинство людей, которых я знаю, кто не удалось их «преобразование в C ++»
Лучший совет, вероятно, - рассматривать их как полностью отдельные языки. Да, большая часть кода C может быть скомпилирована компилятором C ++, но, как правило, это не лучший вариант.
C - очень низкоуровневый хакерский язык. Вы получаете то, что видите. У него есть указатели и структуры, поэтому вы используете указатели и структуры. В нем очень мало безопасности типов, поэтому вы в максимально возможной степени игнорируете безопасность типов.
С другой стороны, C ++ допускает огромное количество абстракций. Вместо указателей вы обычно хотите использовать итераторы, которые концептуально ведут себя как указатели, но не являются (или могут не быть).
Вместо того, чтобы отбрасывать информацию о типе (например, когда функции принимают void *, чтобы они работали с любым типом указателя), вы можете использовать шаблоны, чтобы сохранить безопасность типов и по-прежнему иметь возможность повторно использовать одно и то же определение одной функции.
И вам предоставляется отличная стандартная библиотека, которая позволяет выражать сложные алгоритмы в терминах простых предопределенных строительных блоков.
C ++ - это многопарадигмальный язык. В некоторых ответах здесь говорится, что C ++ объектно-ориентирован, что частично верно. Да, в нем есть поддержка объектно-ориентированного кода, но это не то, что C ++ .
C ++ также поддерживает универсальное программирование, которое часто предпочтительнее ООП. Он также имеет ограниченную поддержку функционального программирования. И конечно же он по-прежнему поддерживает процедурное программирование в стиле C. Уловка C ++ состоит в том, чтобы понять все это, чтобы вы знали, что и когда использовать. В этом сильная сторона C ++ - возможность переключаться между всеми этими парадигмами и смешивать их. Люди, называющие C ++ языком ООП, упускают из виду суть так же сильно, как и люди, называющие его улучшенным языком C. Он позволяет писать код в любом из этих стилей, но ни один из них сам по себе не имеет смысла. C - лучший C-подобный язык, и есть много лучших языков ООП. Если вы хотите придерживаться одной единственной парадигмы, используйте язык, предназначенный для этого.
Люди, называющие C ++ языком ООП, упускают из виду суть так же, как и люди, называющие его улучшенным языком C. Он позволяет писать код в любом из этих стилей, но ни один из них не имеет смысла сами по себе. C - лучший C-подобный язык, и есть много лучших языков ООП. Если вы хотите придерживаться одной единственной парадигмы, используйте язык, предназначенный для этого. Люди, называющие C ++ языком ООП, упускают из виду суть так же, как и люди, называющие его улучшенным языком C. Он позволяет писать код в любом из этих стилей, но ни один из них не имеет смысла сами по себе. C - лучший C-подобный язык, и есть много лучших языков ООП. Если вы хотите придерживаться одной единственной парадигмы, используйте язык, предназначенный для этого.Забавно, сколько здесь людей заявляют, что C и C ++ «совершенно разные», и что «C ++ объектно-ориентированный, C - нет» ...
Во-первых: C ++ изначально был разработан как расширение языка C. Фактически, стандартная документация C ++ отсылает к стандарту C. Верно, что в C ++ многое сделано иначе, чем в C, но утверждать, что эти два понятия полностью разобщены, - это немного далеко. Хороший код C может быть скомпилирован с помощью компилятора C ++, а для некоторых тривиальных проблем решения C и C ++ могут выглядеть почти идентичными.
Во-вторых, не позволяйте обмануть себя, полагая, что C ++ является «объектно-ориентированным языком. ". C ++ - это язык, который поддерживает объектную ориентацию , правда. Но он также поддерживает общее программирование, и процедурное программирование. Сосредоточение внимания только на аспекте ООП C ++ отнимает большую часть его мощи.
Что касается привычек ... не привязывайтесь слишком к строкам в стиле C ( char *
) и массивам ( int foo []
). Оба очень редко используются в C ++, так как есть гораздо более мощные (и удобные) замены, string
и vector
.
Обратите особое внимание на указатели и динамическое распределение памяти. . Хотя в хорошем коде C ++ их очень мало, вы должны знать, как они работают. Делая это, вы также поймете , почему хороший код C ++ инкапсулирует их или заменяет их ссылками, поэтому они не часто появляются в коде производственного качества.
При разработке кода C начните со структурой
, содержащей соответствующие данные (например, поля адреса), а затем создать функции, работающие с этим типом структуры ( address_read (struct address_t *)
, address_write (struct address_t *)
, address_modify_name (struct address_t *, char *)
и т. д.). Добавьте функцию main ()
, которая вызывает эти функции в соответствующем порядке последней. Данные - важная часть программы, а не функция. Это то, что упростит переход к C ++ (и объектной ориентации).
Есть еще кое-что, но я не утверждаю, что отвечу на все в одном сообщении SO. : -)
). Добавьте функцию main ()
, которая вызывает эти функции в соответствующем порядке последней. Данные - важная часть программы, а не функция. Это то, что упростит переход к C ++ (и объектной ориентации).
Есть еще кое-что, но я не утверждаю, что отвечу на все в одном сообщении SO. : -)
). Добавьте функцию main ()
, которая вызывает эти функции в соответствующем порядке последней. Данные - важная часть программы, а не функция. Это то, что упростит переход к C ++ (и объектной ориентации).
Есть еще кое-что, но я не утверждаю, что отвечу на все в одном сообщении SO. : -)
Если вы Я бы порекомендовал первые 3 главы Язык программирования C ++ создателя C ++ Бьярна Страуструпа.
В частности, «Заметки для читателя» и «Путешествие по C ++» дадут вам хорошее представление о том, где и чем C ++ отличается от C, и помогут сфокусировать ваше дальнейшее изучение. Конечно, при работе с C ++ полезно иметь всю книгу под рукой.
Что интересно для вашей ситуации, в главе 1 Бьярн на самом деле говорит
«в продолжающемся споре о том, можно ли нужно выучить C до C ++, я твердо убежден, что лучше ехать прямо на C ++ ».
Конечно, согласился бы, не так ли, но если вы согласитесь с его доводами, вам лучше сразу перейти к C ++ как можно скорее.
Разделяйте языки
C и C ++ могут казаться похожими, но это разные языки с разными правилами для одинаковых конструкций. Если вы можете изолировать одно от другого, тем лучше.
При переходе на C ++ будьте готовы отучиться (изучить другой несовместимый метод) о:
Я предполагаю, что C ++, который вы будете изучать, вероятно, не будет чрезмерно объектно-ориентированным, по крайней мере, это не было в любом случае в моем университете. Мы запускали программы на C ++, по сути, как программы на C.
Обязательно прочитайте, как могут быть реализованы классы, а также познакомьтесь с основами указателей.
Обработка файлового ввода-вывода также будет другой ...
Программы на C ++ совершенно разные. вам лучше потратить время на изучение C ++, чем на работу над элементами C, пытаясь улучшить их для C ++.
Например, даже простая программа Hello World значительно отличается:
C:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
C ++:
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
}
(Примеры из здесь ).
Как 'printf' это функция, тогда как cout - это не функция, а экземпляр класса ostream.
Дополнительная литература: iostream .
По возможности используйте структуры и указатели на функции, чтобы имитировать методы классов и абстрактные методы.
Например, если вы хотите определить транспортное средство, и автомобиль, производный от транспортного средства, использующего C, вы должны написать (извините, я не буду проверять код :-)):
struct Vehicle
{
void (*checkFuel)(Vehicle*);
void (*start)(Vehicle*);
void (*move)(Vehicle*);
void (*stop)(Vehicle*);
}
void start1(Vehicle* v)
{
v->checkFuel(v);
printf("START!");
}
void start2(Vehicle* v)
{
v->checkFuel(v);
printf("VROOOOMM!");
}
struct Car
{
Vehicule base;
int (*klaxon)(Car*);
}
Vehicule* newVehicule()
{
Vehicule* v=(Vehicule*)malloc(sizeof(Vehicule));
v->start= start1;
v->move=
(...)
return v;
}
Car* newCar()
{
Car* c=(Car*)malloc(sizeof(Car));
Vehicule* v=(Vehicule*)c;
v->start= start2;
v->move=
(...)
c->kaxon=(...)
return c;
}
C ++ объектно-ориентированный, C - нет. Так что обычные вещи, такие как поддержание чистоты кода указателя и комментарии к функциям / методам и понимание того, как не получить бесконечные циклы препроцессора с использованием #IFDEF.
Однако объектно-ориентированный подход часто может быть лучше, если на самом деле кодировать, думая об объектах. Так что вам нужно подумать о различии новых функций.
Вот некоторые моменты:
1) Убедитесь, что вы хорошо владеете указателями. Сосредоточьтесь на том, как работают массивы и указатели, каковы сходства и различия между ними.
2) Лучший способ усовершенствовать c - это писать программы. Напишите как можно больше. Для начала вы можете написать собственные функции для некоторых функций библиотеки. Вы можете попробовать свои силы в Strcpy, strcmp, strncpy, memcpy, memmove.
3) Узнайте, как отлаживать. (Gdb действительно крутой).
4) Начните следовать определенному стилю кодирования и постарайтесь придерживаться его.
5) Всегда снабжайте свой код содержательными комментариями.
Стиль программирования на C и C ++ совершенно другой. C ++ - это объектно-ориентированное программирование, а C - процедурно-ориентированное программирование. Программирование на C ++ лучше всего подходит для моделирования реальных проблем с использованием классов / объектов. Но основные концепции, такие как указатели, структуры, операторы, операторы приведения типов, обработка данных, одинаковы в обоих. Структуры и классы имеют схожую концепцию, но не совсем… так что вы можете сконцентрироваться на программировании с использованием структур, указателей, операторов и управления памятью, пока вы учитесь на 'C'
Переход на C ++ означает, что вы почувствовали, что вам нужны классы или лучшие библиотеки. Вот что я чувствую. Я также изучаю лучшие возможности C ++, имея опыт работы в C. До сих пор я смотрел в основном на векторы [помимо классов и шаблонов].
Я считаю, что языки слишком похожи, чтобы
думать о них полностью по отдельности.