Использование / Mixing C в коде C ++? - PullRequest
22 голосов
/ 26 октября 2010

Является ли использование C в C ++ плохим?

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

Я сейчас нафорум, где спор о std::string против char* имеет место.Некоторые люди говорят, что выделение простого блока памяти char* более эффективно, и пока вы его освобождаете, это нормально.С другой стороны, у нас есть люди, которые говорят, что std::string лучше, потому что в нем не задействовано управление памятью, но оно менее эффективно.

Итак, главный вопрос здесь таков:

  • МикшированиеC / C ++ плохо?Стоит ли использовать ТОЛЬКО на С ++ только при написании кода на С ++?

Буду благодарен за любые ответы!

Ответы [ 12 ]

17 голосов
/ 26 октября 2010

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

Это правда;если вы чрезвычайно осторожны и убедитесь, что вы убираете вещи вручную, то это не проблема.Но у вас действительно есть время, чтобы сделать это?Каждый звонок на new может бросить std::bad_alloc.Вы всегда ловите каждое исключение, которое может быть выброшено, и вручную очищаете любые ресурсы?

Я рискнул бы угадать, что ответом будет «нет», потому что писать такой код очень утомительно, и трудно быть абсолютно уверенным, что такой код написан правильно, даже вслучай редких сбоев.

Если ответ «да», то почему вы тратите столько времени на заботу об управлении ресурсами?C ++ идиомы, такие как управление ресурсами с привязкой к области видимости (SBRM; более широко известный как получение ресурсов - инициализация (RAII)), и библиотеки, такие как стандартная библиотека шаблонов, призваны помочь вам легче написать правильный код.Почему дела идут нелегко, когда вам это не нужно?

Стоит ли использовать ТОЛЬКО на 100% C ++ при кодировании C ++?

Да, хотя, если естьбиблиотека C, которая делает то, что вам нужно, или если у вас есть устаревший код C, который вы хотите использовать, вы, безусловно, можете использовать этот код;просто будь осторожен.Часто самый чистый способ взаимодействия с кодом C - это написать оболочку C ++ вокруг него.

12 голосов
/ 26 октября 2010

Я твердо убежден, что ваш вопрос вообще не имеет отношения к C или C ++.Ваш вопрос о торговле сомнительной эффективностью для безопасности.Да, C может быть более эффективным.Но насколько эффективнее?И что вы платите за это?На эти вопросы вы должны ответить.В большинстве случаев издержки string против const char * незаметны.Если вы разрабатываете крайне критичное по эффективности приложение, то почему бы не написать его на языке C в первую очередь?

7 голосов
/ 26 октября 2010

Я искренне удивлен поляризацией в ответах и ​​комментариях.

На мой взгляд, ответ довольно прост:

При написании проекта на C ++ используйтеC ++, избегайте C (и семейства) и придерживайтесь Стандартной библиотеки и STL.Обеспечить однородный интерфейс C ++ (в конце концов, это проект C ++!). При использовании внешнего проекта на C, который написан на C, вы, конечно, можете его использовать.(см. примеры ниже)

Два простых примера:

  1. Напишите программу / библиотеку C ++, которая выполняет научные вычисления.Я бы определенно использовал GSL (Научная библиотека GNU), и он написан на C. Есть только несколько предостережений (таких как специализированные функции инициализации и освобождения для конкретных структур и функций в GSL), которые могут быть включены в std::unique_ptr typedef,Существует также проблема обработки ошибок: проверка кодов ошибок может быть удалена в механизме исключения, если необходимо / желательно, или вы можете сохранить коды ошибок, содержащиеся в функциях вычисления.У GSL есть способ настроить обработчик ошибок, я полагаю, что некоторые другие библиотеки C имеют такую ​​функциональность.

  2. Написание программы на C ++ с использованием Win32 API, который ужасно основан на C.Я говорю об использовании легкого API, например, о чтении файлов в каталоге, проверке, существует ли файл и т. Д., А не о тяжелом GDI + или других вещах.Мне нравится оборачивать все функции C, предоставляемые Win32 API, в приятные функции в стиле C ++, возможно, с необходимыми исключениями и возвращать std::string вместо необходимости передавать буфер char* в качестве аргумента.

Я понимаю, что оба примера довольно ... поверхностны ... но я чувствую, что они выражают достаточно общую идею.

4 голосов
/ 19 октября 2011

Да, смешивать C и C ++ плохо, любая причина не имеет ничего общего с производительностью или безопасностью:

Это плохая причина ремонтопригодности:
* программист C ++ ожидает, что весь код будет вести себя как C ++.
* программист на C ожидает, что весь код будет вести себя как C.

Поэтому, когда вы смешиваете C ++ и C, вы нарушаете ожидания обоих программистов о том, как все должно работать.

3 голосов
/ 27 октября 2010

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

2 голосов
/ 26 октября 2010

Ответ, конечно: это зависит.

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

Использование C для производительности хорошо, если вы осторожны.Но вы должны делать это только в том случае, если ЗНАЕТЕ, что вам нужна производительность.Преждевременная низкоуровневая оптимизация - работа дьявола.

Это очень редкий случай, когда использование char * по сравнению с std :: string даст вам заметные преимущества в производительности, и это стоит затрат на управление памятью только в тех случаях, когда это точно.

2 голосов
/ 26 октября 2010

изменение аргумента через std :: string против char *.

std :: string не будет медленнее, чем char * (для heap char *); многие реализации намного быстрее, потому что они используют частный пул памяти. И в любом случае надежность std :: string значительно перевешивает любой (маловероятный) перфомент

1 голос
/ 27 октября 2010

Если вы говорите о методах, я бы с осторожностью сказал, что выполнение вышесказанного - это нормально.

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

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

1 голос
/ 27 октября 2010

В конкретном случае string против const char * вы должны использовать голые const char * для всех переменных, которые содержат строковые константы только строковые константы), конвертируяstring только при переходе к API, который требует string.Постоянное выполнение этого может устранить огромное количество глобальных конструкторов, не вызывает головной боли при выделении памяти (поскольку строковые константы являются постоянными, постоянными данными), а IMO фактически делает код более понятным - вы видите const char *, вы знаете, что это будет строковая константа.

1 голос
/ 27 октября 2010

Является ли использование C в C ++ плохим?

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

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

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

я обычно проверяю / отклоняю / переписываю код, который входит в кодовые базы, которые "c с функциями c ++" или "c ++ с функциями c".я даже зашел так далеко, что изменил malloc, free и т. д. для утверждения в корневых пространствах имен (между прочим).

В настоящее время я на форуме, где аргумент перед std :: string vs. char * происходит.Некоторые люди говорят, что выделение простого блока памяти char * более эффективно, и пока вы его освобождаете, это нормально.С другой стороны, у нас есть люди, которые говорят, что std :: string лучше, потому что в нем не задействовано управление памятью, но он менее эффективен.

, есть больше опций для представления строки в c ++, чем в std ::string.

, на мой взгляд, совершенно правильно создать новый класс, который представляет строку и служит определенной цели или следует дополнительным контрактам (когда это необходимо).часть контрактов таких строковых представлений заключается (конечно) в том, что они управляют своими собственными ресурсами, используя new[]/delete[], когда используется динамическая память.

, если эффективность так важна, а std::string меньше, чем идеально дляВ этом случае c ++ достаточно мощный, чтобы выразить свое намерение в этих конкретных случаях, создав специализированный интерфейс на c ++.Есть много случаев, когда это приемлемо (IMO), но не всегда стоит затрат времени.в любом случае, им легче управлять, чем интегрировать идиомы / стили / опасности в программы на c ++.

Итак, главный вопрос здесь: плохо ли смешивать C / C ++?Если вы используете ТОЛЬКО на 100% C ++ при кодировании C ++?

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

...