Что следует иметь в виду при портировании с C на C ++ - PullRequest
5 голосов
/ 18 ноября 2008

Что следует иметь в виду при преобразовании моих проектов из C в C ++? Есть ли какая-либо причина использовать C вообще? Сейчас я думаю только о том, чтобы убедиться, что это дружественно к DLL, чтобы я мог создать интерфейс C, если мне это нужно.

Примечание: я хорошо знаю C ++. Шаблоны, частичная специализация, почему множественное наследование плохо (я видел только одно правильное использование для него) и т. Д. Я в основном хочу знать, почему я бы использовал C над C ++. Библиотеки DLL и привязки языка сценариев - одна из причин. Так что мне просто нужно помнить, что у меня должен быть интерфейс C для определенных вещей. Есть что-нибудь еще?

Ответы [ 9 ]

16 голосов
/ 18 ноября 2008

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

Если у вас есть работающая библиотека C, и вы хотите, чтобы она имела более «интерфейс C ++ ish», то оборачивать ее в классы может быть разумнее, чем конвертировать ее. Конечно, это удовлетворяет требованию предоставить DLL-дружественный интерфейс C: оставьте тот, который у вас уже есть.

11 голосов
/ 18 ноября 2008

Как программист на C, меня раздражает, когда программисты на C ++ пытаются "перенести" C на C ++. Хотя есть много преимуществ использования структур языка C ++, они не всегда улучшают простой функционально-ориентированный подход C. Поскольку вы всегда можете получить функциональность C с помощью extern "C", нет особых причин изменять рабочий код. В проектах, над которыми я работал, создание оберток объектов вокруг кода C работало хорошо. Таким образом, основной код может быть разделен между командами, работающими на любом языке, и каждый может использовать интерфейс, соответствующий их среде. Мы даже «перенесли обратно» некоторый код C ++ на C, чтобы стимулировать повторное использование кода.

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

7 голосов
/ 09 августа 2010

Поскольку я перенес несколько C проектов на C ++ , прежде чем я смогу передать свой опыт:

Я предполагаю, что на самом деле вы имеете в виду «Делать классы и объекты из кода, который уже работает нормально», когда вы говорите, что переносите с C на C++. Это, вероятно, то, что вы делаете. Я предполагаю, что причина, по которой вы хотите сделать перенос, состоит в том, чтобы сделать код более пригодным для повторного использования и поддержки. Имейте в виду, я предполагаю, что это проект среднего и большого размера (не менее 10000 LOC).

Если это так, то я могу представить некоторые проблемы, с которыми вы столкнетесь, но это также и проблемы, которые встречаются в C ++ в целом:

Недавно внесенные ошибки при его создании

'OO'**

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

Проблемы с управлением памятью

C malloc и free и C ++ new и delete делают очень разные вещи. То, как будут распределяться ваши объекты C ++, будет во многом зависеть от того, как вы переосмыслили свое понимание того, что делает код C, и поэтому вам нужно быть очень опытным в обоих случаях. Но сначала я бы оставлял вызовы malloc и free и просто абстрагировал их с помощью C ++, если только для этого нет веских причин. Таким образом, как только ваши классы созданы и выделяют и освобождают память, ваше приложение будет иметь утечки памяти. Это гарантия и самая причина, по которой вы должны проводить тестирование постепенно.

Рефакторинг и дизайн шаблонов

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

Глобал

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

5 голосов
/ 18 ноября 2008

Вы всегда можете включить необработанный код C в проект C ++. Таким образом, даже если у вас есть библиотека C, которая в некоторой степени мешает C ++, просто используйте extern "C" {} для ссылок, а затем вызовите ее внутри кода C ++.

https://isocpp.org/wiki/faq/mixing-c-and-cpp

Также возможно связать объектные файлы C с объектными файлами C ++.

Это (ссылка на c ++ Super-FAQ) в основном все, что вы знаете, чтобы преобразовать ваш проект в C ++ и сохранить совместимость с прежними версиями.

1 голос
/ 15 марта 2009

почему множественное наследование плохо

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

1 голос
/ 18 ноября 2008

Есть ли какая-либо причина использовать C вообще?

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

1 голос
/ 18 ноября 2008

Основной проблемой будут ключевые слова. Вы использовали 'new', 'private', 'public' и т. Д. В качестве имен переменных?
Если вы не нацелены на конкретную встроенную платформу или драйвер режима ядра, нет никакой реальной необходимости ограничивать себя до 'c'.
Вы не получите всех преимуществ C ++, просто написав код на c в компиляторе c ++ - конечно, это требует немного большего переосмысления!

0 голосов
/ 18 ноября 2008

Есть ли какая-либо причина использовать C вообще?

Код C ++ компилируется слишком медленно для небольших проектов.
Длинная компиляция мешает циклу: написать код -> проверить его -> написать больше кода -> проверить это ...

0 голосов
/ 18 ноября 2008

Да. C-код кажется проще для небольших проектов; LOC-мудрый и двоичный.

...