Використовуючи C ++, але не використовуючи особливості мови, слід перейти на C?


16

Я розвиваю емулятор NES як хобі, у вільний час. Я використовую C ++, оскільки мова, якою я в основному користуюся, знаю здебільшого і люблю в основному.

Але тепер, коли я заздалегідь просунувся в проекті, я розумію, що не використовую майже ніяких конкретних особливостей C ++, і міг би це зробити в простому С і отримати той самий результат. Я не використовую шаблони, перевантаження оператора, поліморфізм, успадкування. То що б ви сказали? я повинен залишитися в C ++ або переписати його на C?

Я не буду робити це для підвищення продуктивності, це може стати побічним ефектом, але ідея: чому я повинен використовувати C ++, якщо він мені не потрібен?

Єдиними особливостями C ++, які я використовую, є класи для інкапсуляції даних та методів, але це можна зробити так само, як і структури та функції, я використовую нове та видалення, але також можу використовувати malloc та free, і я використання успадкування лише для зворотних викликів, які можна було б досягти за допомогою покажчиків на функції.

Пам'ятайте, це хобі-проект, у мене немає термінів, тож накладний час та робота, які потребували б переписування, не є проблемою, можливо, також будуть цікавими. Отже, питання C чи C ++?


3
Мені здається, ви вже відповіли собі: навіщо використовувати C ++, якщо вам потрібен лише C? Є багато ситуацій, в яких C абсолютно гаразд.
Джорджіо

3
@Giorgio: І всі вони випаровуються через перші шістдесят секунд, і вам потрібно зберегти свій код.
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.І це відповідь на ваше запитання. Ви повинні перемикати мови середнього проекту лише тоді, коли є проблема, яку поточна мова не може вирішити. I don't use templates, operator overloading, polymorphism, inheritance.Навчатися та використовувати поняття було б набагато корисніше, ніж переходити на C. Оскільки це проект хобі, чому б не використати кілька речей, якими ви раніше не користувалися? Ви завжди можете розпочати інший проект на мові C та вивчити мову, але для вашого поточного проекту не має сенсу перемикатися.
yannis

4
Я не використовую 100% мови в кожному проекті, про який я пишу. Ви найкраще знаєте C ++, можливо, ви знайдете вагомі причини використовувати функції, які раніше не знайшли. Ви можете почати лікування C ++ як набагато більш безпечним С, як тільки ви почнете використовувати стандартний матеріал бібліотеки і бустер конструкти подобається std::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::mapі т.д. Для функції зворотного виклику, вид в використання функторів, і в C ++ 11, вам можна також почати використовувати такі речі, як лямбда-функції.
wkl

3
@Giorgio: Так. Прокрутка нескінченного пов'язаного списку обов'язково призведе до зайвих помилок.
DeadMG

Відповіді:


40

Ви зараз не використовуєте це, але наступного разу, коли ви протікаєте пам'ять або отримуєте подвійне видалення, ви будете просити повернутися до std::vector<T>, std::unique_ptr<T, Del>і std::shared_ptr<T>це може вирішити ці проблеми легко - майже тривіально. Це те, що відбувається з усіма, хто використовує C над C ++, з часом, і розумніші просто не чекають, коли помилки з’являться перед тим, як переїхати.

Код, який використовує newта deleteбезпосередньо насправді не належить до C ++, він належить до тієї половини, яку ми називаємо "C з класами". Ось де ця мова була приблизно в 1985 році. Це не особливо схоже на C ++, приблизно в 2011 році. За всією ймовірністю, де б ви не вивчали C ++, просто не дуже добре вчили це - чомусь, на жаль, є досить загальним - і з кращою освітою ви б знайти використання цих функцій.

Зокрема, як я перераховував вище, загальні структури даних C ++ та класи управління ресурсами просто принципово перевершують все, що може запропонувати C. Якщо ви хочете динамічно розподілений масив, тоді використовуйте std::vector<T>. Це досить поширений випадок використання. Якщо ви їх не використовуєте, тоді ваш код загрожує великою небезпекою помилок, особливо пов'язаних з управлінням ресурсами. C ++ може гарантувати безпеку та повторне використання коду таким чином, що C ніколи не може торкатися.

Однак я думаю, що ви також могли занадто багато очікувати. Написання шаблонів і перевантаження операторів не є звичним для користувачів бібліотеки. Якщо ваш код використовує std::vector<T>, вам не потрібно писати шаблон, щоб це сталося. Якщо ваш код використовується std::string, ніхто не змушує вас перевантажувати операторів. Вам потрібно лише зробити ці речі, щоб написати std::vector<T> і std::string- але ви все-таки зможете ними повністю скористатися.

Поліморфізм / успадкування також має лише конкретний випадок використання. Якщо ваш код не вимагає від вас запису шаблонів або використання віртуальних функцій, це не відбувається, і є програми або сегменти програм, де вам не потрібно писати власні шаблони.

Крім того, у програмі C над C ++ виграш не працює.


1
@Giorgio: make_sharedіснує, і ви можете написати тривіальний make_uniqueшаблон, який виконує ту саму роботу. Це безпечніше.
DeadMG

4
Чудова відповідь. Цвях на голові. C ++ є найціннішим для цих маленьких бібліотек, якими ми завжди повинні користуватися.
Андрес Яан Так

2
@Giorgio: Це небезпечно, оскільки, викликаючи кілька подібних аргументів, ви можете отримати витік пам’яті у випадку винятку і make_sharedє більш ефективним. Тільки заводські функції можуть гарантувати безпеку виключень.
DeadMG

6
@ tp1: WTF? Англійською, будь ласка.
DeadMG

2
@Lohoris Не потрібно цитування здорового глузду. Яким чином C повинен бути більш ефективним, ніж C ++?
Кріс каже, що повернемо Моніку

7

Навіть якщо ви не використовуєте специфічні для C ++ функції, компілятор C ++ спричинить більше проблем, ніж C, через більш жорстку систему типу C ++.


6

Я би дивився на це з іншого напрямку. Ви щось отримаєте , переписавши код на C? Навіть на проект, що займається суто хобі, є вартість, пов’язана з таким переписанням. Якщо нічого іншого, то, напевно, можна було б назвати додатковою вартістю, тобто інші речі, які ви могли б зробити за той час, якби ви не витрачали свій час, переписуючи його в C.

Підсумок: якщо ви не вважаєте, що код справді може бути використаний в умовах, де доступ до C ++ дійсно обмежений (або його немає), це було б в кращому випадку безглуздою марною тратою часу. Принаймні, як на моєму досвіді, зазвичай це дуже швидко виходить за рамки цього - обдумуючи код, який я написав на C ++ потрібно було перетворити на C, я можу досить чітко пам'ятати, що навіть у досить багатьох випадках, коли це здавалося це має бути тривіально, я використовував набагато більше функцій, характерних для C ++, ніж я спочатку зрозумів. Щоб сподіватися на корисність взагалі, вам доведеться орієнтуватися на C89 / 90, і в такому випадку вам швидко нагадають про такі речі, як, наприклад, визначення всіх змінних на початку блоку, а не де вони є насправді б / в.

Коротше кажучи, якщо ви майже впевнені, що переписування на C принесе справжню користь, майже неминуче можна зробити багато кращих справ.


+1 Деякий час тому мені довелося написати бібліотеку для використання в іншому проекті C, і я подумав, що це було б гарною ідеєю також впровадити її в C, людино, який я дурний ідіот тоді був.
Кріс каже, що знову

1

Як більш загальна відповідь:

Не перемикайтесь на C ++ лише тому, що ви використовуєте деякі його більш унікальні функції. Одного разу вам можуть знадобитися ці функції, і ви будете просто бити головою, оскільки ви використовуєте C.


1

Для розвитку хобі я б розглядав можливість повернення до звичайної мови C. С та мови, подібні до С, швидше за все підтримуються на крихітних модулях розвитку хобі.

Багато відповідей тут можуть бути від професійних типів програмного забезпечення. Як любитель, ви не будете кодувати постійно чи повний робочий день. Тож подумайте, якою мовою ви швидше запам’ятаєте або забудете примхи, якщо ви подаєте проект на рік, а потім поверніться та спробуйте прочитати свій код після того, як ви заржавіли в кодуванні. C ++, що має більш багатий набір функцій, може зайняти більше або менше часу для його повторного придбання, залежно від стилю кодування.


1

Відповісти на ваші запитання непросто, оскільки ми не знаємо, чи працюєте ви над проектом над вдосконаленням своїх мовних специфічних навичок (C vs C ++) або для вдосконалення інших навичок програмування (проектування, вирішення проблем тощо).

"Єдиними особливостями C ++, які я використовую, є класи для інкапсуляції даних та методів, але це можна зробити так само, як і структури та функції". Це не правда. structsв C не підтримують інкапсуляцію і не можуть містити функції (методи) - принаймні, не без використання таких методів, як покажчики на функції. Крім того, функції в C слабші, тому що їх не можна перевантажувати.

"Я використовую нове та видалення, але можу також використовувати malloc та free, і я використовую спадщину лише для зворотних викликів, які можна досягти за допомогою покажчиків на функції." Як зазначалося deadmg, використання безпосередньо newта deleteв C ++ не рекомендується. Крім того, спадкування IMHO (та GoF) в OOP слід віддавати перевагу над композицією лише тоді, коли потрібен поліморфізм. І я не думаю, що домогтися поліморфізму (пізнього зв'язування) в C за допомогою покажчиків на функції тривіально.

Крім цього, я не намагатимусь переконати вас, що C ++ "кращий", ніж C, оскільки це питання переваги, і це завжди залежить від проблеми, яку ви намагаєтеся вирішити (використання функцій OOP для розробки емулятора NES може бути гарна ідея).


1
structsв C, насправді, можна використовувати для інкапсуляції методів. Ви просто створите структуру покажчиків функцій та ініціалізуєте їх, щоб вказати на потрібні функції. Погляньте на приклад lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 .
Роберт Мартін

Це вірно. Дякую за коментар, я продовжив відповідь.
sakisk

Приємно. Ще один ніт: функції в C можуть бути перевантажені (подумайте printf), але при цьому ви втратите будь-яку перевірку типу. Немає можливості мати обмежений набір прийнятних декларацій: це або 1 (і ви отримуєте перевірку типу), або "багато" (і втрачаєте перевірку всіх типів, з великим особистим ризиком). Як і в більшості речей у С, це можливо, але часто незручно.
Роберт Мартін

Покажчики на функції - це вдосконалена техніка С? Дійсно?
Стипендіати доналу

@DonalFellows Ви праві, я перебільшував. Видалено просунуте ... :)
sakisk

0

Я дуже початківець, тому ось мої 2 біти.

Я вивчаю C та C ++ на Wibit.net з кількома приємними базовими відеоуроками, можливо, вони можуть вам дуже допомогти переглянути огляд "ситуації" (не оголошення!)

Я раджу вам перейти на C, аби тільки навчитися, оскільки ви є любителем, це буде приємно, а не проблема.

Я раджу більше. Робіть це на обох мовах. Порівняйте спосіб і рішення, які ви знайдете та використовуєте. Я впевнений, що буде не так "просто", як ви очікували ... але впевнений, що ви багато чого навчитесь!


1
Дуже дякую, але я не навчаюсь, я вже знаю C та C ++, я прошу, який саме використовувати для цього конкретного проекту.
Петруза

ой, мій час вчитися! = P
H_7

1
Також я б порадив, що замість відеоуроків ви отримуєте книги Кернігана та Строструпа, хороший IDE (Visual Studio, Eclipse, Xcode) та навчаєтесь, кодуючи приклади, проби та помилки та вдаючись до stackoverflow.
Петруза

-1

Ось плюси і мінуси C ++ проти C:

  1. Перехід до C полегшить перебування в обраному підмножині C ++, тому що компілятор тоді дасть помилку, коли ви виходите за його межі. Якщо основна проблема полягає у перебуванні в межах визначеного підмножини, слід вибрати цю альтернативу. (чому б ми не мали підтримки для цього компілятора?)
  2. Після того, як ви зможете залишитися у вибраному підмножині функцій c ++, наступне - спробувати змінити підмножину, щоб позбутися поганих умов, які порушують код. Для цього потрібно використовувати цілий c ++.
  3. Після того, як у вас є "перебування в підмножині" і "це хороша підмножина", тоді перейдіть за межі функцій c ++ і починайте думати про вимоги.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.