it-swarm-eu.dev

Jak se liší C od C ++?

Mnoho lidí uvedlo, že C++ je zcela odlišný jazyk než C, ale sám Bjarne řekl, že C++ je jazyk, který je rozšířen od C, odtud pochází ++. Proč tedy všichni neustále říkají, že C a C++ jsou zcela odlišné jazyky? Jakým způsobem se liší C od C++ než rozšířené funkce v C++?

21
Joshua Partogi

V 80. letech, kdy se vývoj C++ teprve začínal, byl C++ téměř správným supersetem C. Takto to všechno začalo.
Postupem času se však C a C++ vyvíjely a od sebe navzájem se lišily, přestože kompatibilita mezi jazyky je vždy považována za důležitou.

Kromě toho technické rozdíly mezi C a C++ způsobily, že typické idiomy v těchto jazycích a to, co se považuje za „osvědčené postupy“, se ještě více liší.

To je hnací faktor lidí, kteří říkají věci jako „neexistuje žádný takový jazyk jako C/C++“ nebo „C a C++ jsou dva různé jazyky“. Přestože je možné psát programy, které jsou přijatelné pro kompilátor C i C++, kód se obecně nepovažuje za příklad dobrého kódu C ani za příklad dobrého kódu C++.

18

Stroustrup sám odpoví, že v jeho FAQ :

C++ je přímý potomek C, který si zachovává téměř všechny C jako podmnožinu. C++ poskytuje silnější kontrolu typu než C a přímo podporuje širší škálu stylů programování než C. C++ je „lepší C“ v tom smyslu, že podporuje styly programování prováděné pomocí C s lepší kontrolou typu a podporou notace (bez ztráty) účinnosti). Ve stejném smyslu je ANSI C lepší C než K&R C. Kromě toho C++ podporuje abstrakci dat, objektově orientované programování a obecné programování.

Je to podpora objektově orientovaného programování a generického programování, díky kterému je C++ „úplně odlišný“ od C. Vy můžete téměř napsat čistý C a pak jej zkompilovat s Kompilátor C++ (pokud se staráte o přísnější kontrolu typu). Ale pak stále píšete C - nepíšete C++.

Pokud píšete C++, pak využíváte objektově orientované a šablony funkce a to není nic, co byste viděli v C.

20
Dean Harding

Jednoduše řečeno, to, co je v C považováno za idiomatické, v C++ rozhodně není idiomatické.

C a C++ jsou v praxi velmi odlišné jazyky kvůli způsobu, jakým je lidé používají. C se zaměřuje na minimalizmus, kde C++ je velmi složitý jazyk, s lot funkcí.

Existují také některé praktické rozdíly: C lze snadno volat z téměř jakéhokoli jazyka a často definuje ABI platformy, zatímco C++ je docela obtížné používat z jiných knihoven. Většina jazyků má rozhraní FFI nebo rozhraní v jazyce C, dokonce i jazyky implementované v jazyce C++ (například Java).

13
David Cournapeau

Kromě zřejmé skutečnosti, že C++ podporuje objektově orientované programování, si myslím, že zde máte odpověď: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++

Tento článek obsahuje příklady kódu ukazující věci, které jsou v pořádku v jazyce C, ale nikoli v jazyce C++. Například:

int *j = malloc(sizeof(int) * 5); /* Implicit conversion from void* to int* */

Přenesení programu C na C++ je často jednoduché a spočívá většinou v opravě chyb při kompilaci (přidání obsazení, nová klíčová slova atd.).

4
Martin Wickman

C++ přidává nejen nové funkce, ale nové koncepty a nové idiomy do C. I když jsou C++ a C úzce spjaty, faktem zůstává, že pro efektivní psaní v jazyce musíte myslet ve stylu tohoto jazyka. Ani ten nejlepší C kód nemůže využít různých sil a idiomů C++, a tak je pravděpodobnější než ne ve skutečnosti spíše špatný C++ kód.

2
Jon Purdy

"Rozšířené funkce", uděláte to, aby to znělo jako v C++, které přidaly jako, variadic makra nebo tak něco, a to je vše. "Rozšířené funkce" v jazyce C++ jsou úplné přepracování jazyka a zcela nahrazují nejlepší postupy C, protože nové funkce C++ jsou mnohem lepší než původní funkce C, takže původní funkce C jsou zcela a naprosto nadbytečné ve většině případů. Tvrzení, že C++ pouze rozšiřuje C naznačuje, že moderní bojový tank rozšiřuje Butterknife za účelem vedení války.

2
DeadMG

Rozdíl je v tom, že v C uvažujete procedurálně a v C++ myslíte objektově. Jazyky jsou velmi podobné, ale přístup je velmi odlišný.

1
Ant

Zatímco C++ může být v syntaktických termínech super sada C - tj. Jakýkoli konstrukt programu C může být kompilován kompilátorem C++.

Téměř nikdy však nebudete psát programy C++, jako byste to dělali s programem C. Seznam může být nekonečný nebo může být někdo, kdo by měl udělat více výzkumu, aby byl vyčerpávající. Uvádím však několik ukazatelů, které způsobují zásadní rozdíly.

Účelem aktuálního příspěvku je, že C++ má následující funkce, které musí dobrí programátoři C++ použít jako nejlepší postupy při programování, i když je možné kompilovat ekvivalent C.

Jak by se to mělo dělat v C++ nad C

  1. Třídy a dědičnost. To jsou nejdůležitější rozdíly, které umožňují systematickou orientaci na objekt, díky čemuž je programovací výraz velmi silný. Myslím, že - tento bod nepotřebuje lepší vysvětlení. Pokud jste v C++ - téměř vždy, je lepší využívat třídy.

  2. Privatizace - Třídy a dokonce i struktury mají to, co jsou soukromí členové. To umožňuje zapouzdření třídy. Ekvivalentem v C je typcasting objektu jako neplatné * do aplikace, takže aplikace nemá přístup k interním proměnným. V C++ však můžete mít prvky s veřejnými i soukromými třídami.

  3. Projít referencí. C++ umožňuje úpravy založené na referencích, pro které je požadováno předávání ukazatelů. Pass-by-reference udržuje kód velmi čistý a bezpečnější proti nebezpečí ukazatele. Můžete také projít styl C ukazatel a to funguje - ale pokud jste v C++, jste lepší, pokud

  4. nové a smazat vs. malloc a zdarma. Nové příkazy () a delete () nejen přidělují a delokují paměť, ale také umožňují, aby se kód spustil jako součást destrukčního eru, který má být volán v řetězci. Pokud používáte C++ - je ve skutečnosti BAD používat malloc a zdarma.

  5. Typy IO a přetížení operátora Přetížení operátora umožňuje dobře čitelný kód nebo intuitivnější kód. Stejné pro operátory << a >> io. C způsob, jak toho dosáhnout, by bylo použití funkčních ukazatelů - ale je to chaotický a pouze pro pokročilé programátory.

  6. Pomocí "řetězec". Char * od C funguje všude. Takže C a C++ jsou skoro stejné. Nicméně, pokud jste v C++ - je vždy mnohem lepší (a bezpečnější) používat třídy String, které vás ušetří před nebezpečím matic při běhu, což jsou téměř všechny věci.

Funkce bych stále nebyl fanoušek v C++ 1. Šablony - I když nepoužívám těžké šablony v mnoha kódech - může se ukázat jako velmi silný pro knihovny. Neexistuje téměř žádný ekvivalent toho v C. Ale za normálního dne - zvláště pokud děláte matematicky chybějící.

  1. Inteligentní ukazatele - Ano, jsou velmi inteligentní! A jako většina inteligentních věcí - začnou dobře a později se stanou chaotickými! Nemám ráda použití

Věci, které se mi líbí o C a chybějí v C++

  1. Polymorfní algoritmy pomocí funkčních ukazatelů. V C, když provozujete složité algoritmy - někdy můžete použít sadu funkčních ukazatelů. Díky tomu je výkonný polymorfismus mocným způsobem. Když jste v C++, můžete [~ # ~] [~ # ~] používat funkční ukazatele - ale to je špatné. Měli byste používat pouze metody - jinak byste měli být připraveni na nepořádek. Jedinou formou polymorfismu ve třídách C++ je přetížení funkcí a operátorů, ale to je docela omezující.

  2. Jednoduchá vlákna. Při vytváření podprocesů byly pthreads - je to docela jednoduché a zvládnutelné. Stává se, když potřebujete vytvořit vlákna, která mají být třídám „soukromá“ (aby měli přístup k soukromým členům). Existuje boost typ rámců - ale nic v základní C++.

Dipan.

0
Dipan Mehta

Určité jazykové funkce, i když se jedná o doplňky, mohou změnit celý způsob, jakým je třeba jazyk prakticky používat. Jako jeden příklad zvažte tento případ:

lock_mutex(&mutex);

// call some functions
...

unlock_mutex(&mutex);

Pokud by výše uvedený kód zahrnoval volání funkcí implementovaných v C++, mohli bychom být ve světě problémů, protože kterékoli z těchto volání funkcí může házet a my nikdy neodemkneme mutex v těchto výjimečných cestách.

Destruktory již nejsou v oblasti komfortu, aby pomohly programátorům v tomto okamžiku zapomenout uvolnit/uvolnit zdroje. RAII se stává praktickým požadavkem, protože není lidsky možné předvídat každý jednotlivý řádek kódu, který může házet v netriviálních příkladech (nemluvě o tom, že tyto řádky nemusí nyní házet, ale mohou později se změnami). Vezměte další příklad:

void f(const Foo* f1)
{
    Foo f2;
    memcpy(&f2, f1, sizeof f2);
    ...
}

Takový kód, i když je obecně neškodný v C, je jako hellfire vládnoucí zmatek v C++, protože memcpy buldozuje přes bity a bajty těchto objektů a obchází věci jako konstruktéry kopií. Takové funkce jako memset, realloc, memcpy, atd., Zatímco každodenní nástroje mezi vývojáři C zvyklé dívat se na věci poměrně homogenním způsobem bitů a bajtů v paměti, jsou není harmonický s komplexnějším a bohatším typem systému C++. C++ podporuje mnohem abstraktnější pohled na uživatelem definované typy.

Takže tyto typy věcí již neumožňují C++, aby kdokoli, kdo to chce správně používat, na to pohlížel jako na pouhou „nadmnožinu“ C. Tyto jazyky vyžadují k efektivnímu využití nejrůznějších způsobů myšlení, disciplíny a způsobu myšlení. .

Nejsem v táboře, kde je C++ ve všech ohledech naprosto lepší a ve skutečnosti většina mých oblíbených knihoven třetích stran jsou knihovny C z nějakého důvodu. Nevím, proč přesně, ale C libs mají tendenci být minimalističtější povahy (snad proto, že neexistence tak bohatého typu systému nutí vývojáře více zaměřit na poskytování minimální požadované funkce, aniž by budování nějaké velké a vrstvené sady abstrakce), i když často končím pouhým umístěním obalů C++, abych zjednodušil a přizpůsobil jejich použití pro mé účely, ale ta minimalistická povaha je pro mě výhodnější, i když to dělám. Opravdu miluji minimalismus jako přitažlivou vlastnost knihovny pro ty, kteří potřebují více času na to, aby hledali takové vlastnosti, a možná C má tendenci to povzbuzovat, i když pouze na základě skutečnosti, že takový velký a vrstvený a abstraktní kód by byl skutečné PITA rozvíjet v C.

Upřednostňuji C++ mnohem častěji než ne, ale ve skutečnosti jsem povinen používat C API spíše často pro co nejširší binární kompatibilitu (a pro FFI), i když je často používám v C++, přestože používám C pro záhlaví. Ale někdy, když jdete opravdu nízkoúrovňově, jako je úroveň alokátoru paměti nebo velmi nízkoúrovňové datové struktury (a jsem si jistý, že mezi těmi, kdo provádějí vestavěné programování, existují další příklady), může být někdy užitečné být dokážou předpokládat, že typy a data, se kterými pracujete, neobsahují určité funkce, jako jsou vtables, costructors a destruktory, takže s nimi můžeme zacházet jako s bity a bajty, které se budou zamíchat, kopírovat, zdarma a znovu přidělovat. U velmi zvláště nízkoúrovňových problémů může být někdy užitečné pracovat s mnohem jednodušším typovým systémem, který poskytuje C, a samozřejmě má tendenci se stavět rychleji a tak dále.

vysvětlení

Jeden zajímavý komentář, zde jsem chtěl odpovědět do hloubky (shledávám, že zde jsou komentáře přísné, pokud jde o omezení počtu znaků):

memcpy(&f2, f1, sizeof f2); je také „hellfire vládnoucí zmatek“ v C, pokud Foo má nějaké vlastní ukazatele, nebo je ještě horší, protože vám také chybí nástroje, jak se s tím vypořádat.

To je fér, ale všechno, na co se zaměřuji, je hlavně se zaměřením na systém typu C++ a také s ohledem na RAII. Jedním z důvodů, proč takové x-rayish byte-copy memcpy nebo qsort typy funkcí představují menší praktické nebezpečí v C, je to, že zničení f1 A f2 Výše ​​jsou explicitní (pokud dokonce potřebují netriviální destrukci), zatímco když se destruktory přesunou do obrazu, stanou se implicitní a automatizované (často s velkou hodnotou pro vývojáře). To by nemělo zmínit ani skrytý stav jako vptrs a tak dále, které by takové funkce přímo buldozovaly. Pokud f1 Vlastní ukazatele a f2 Mělké kopie je v některých dočasných souvislostech, pak to nepředstavuje žádný problém, pokud se nepokusíme explicitně osvobodit ty vlastnící ukazatele podruhé. S C++ to je něco, co kompilátor bude chtít automaticky dělat.

A to se stává větší , pokud typicky v C, " If Foo má vlastní ukazatele “, protože výslovnost vyžadovaná při správě zdrojů často způsobí, že se něco obvykle obtížněji přehlédne, zatímco v C++ můžeme UDT učinit již nepatrně konstruovatelným/zničitelným pouze tím, že uložíme jakoukoli členskou proměnnou, která není ' • Triviálne konstruktivní/destruktivní (způsobem, který je obecně velmi užitečný, znovu, ale ne pokud jsme v pokušení používat funkce jako memcpy nebo realloc).

Mým hlavním cílem není snažit se argumentovat žádnou výhodou této výslovnosti (řekl bych, že pokud existují, jsou téměř vždy váženi nevýhodami zvýšené pravděpodobnosti lidské chyby, která s ní souvisí), ale pouze říci, že funkce jako memcpy a memmove a qsort a memset a realloc a tak dále nemají místo v jazyce s UDT tak bohatými na funkce a schopnosti jako C++. I když existují bez ohledu na to, myslím si, že by nebylo příliš sporné říci, že drtivá většina vývojářů C++ by byla moudrá vyhýbat se takovým funkcím, jako je mor, zatímco tyto funkce jsou v C každodenní a já jsem d argumentovat, že oni představují méně problémů v C z jednoduchého důvodu, že jeho typový systém je hodně více základní a, možná, “hloupější”. Rentgenové typy C a jejich zpracování jako bitů a bajtů je náchylné k chybám. Dělat to v C++ je patrně prostě naprosto chybné, protože takové funkce bojují proti velmi základním rysům jazyka a proti tomu, co podporuje typový systém.

To je ve skutečnosti největší výzva pro mě, C, konkrétně s tím, jak se to týká jazykové interoperability. Bylo by mnohem, mnohem obtížnější udělat něco jako CFI FFI, aby pochopil plně rozvinutý typ systému a jazykové vlastnosti C++ až po konstruktory, destruktory, výjimky, virtuální funkce, přetížení funkcí/metod, přetížení operátorů, všechny různé typy dědičnost atd. S C je to relativně těžkopádný jazyk, který se stal standardem, pokud jde o API, tak, že mnoho různých jazyků lze importovat přímo prostřednictvím FFI nebo nepřímo prostřednictvím některých exportních funkcí C API v požadované podobě (např .:Java Native Interface). A to je místo, kde mi většinou nezbývá nic jiného než používat C, protože ta jazyková interoperabilita je v našem případě praktickým požadavkem (i když často jen píšu C rozhraní s C++ implementace za nimi).

Ale víte, jsem pragmatik (nebo se alespoň snažím být). Pokud by C byl tento nejnepříznivější a nejbohatší, nejnebezpečnější, nejistý jazyk, někteří z mých nadšenců C++ prohlásili, že to je (a já bych si počítal s nadšencem C++ kromě toho, že to nějak nevede k nenávisti k C z mé strany) ; naopak, mělo to na mě opačný účinek, protože mě přiměl ocenit oba jazyky lépe ve svých vlastních ohledech a odlišnostech), pak bych očekával, že se projeví v reálném světě v podobě těch nejchytřejších a nejvtipnějších a nespolehlivé produkty a knihovny psané v C. A to nenajdu. Mám rád Linux, líbí se mi Apache, Lua, zlib. Považuji OpenGL za tolerantní pro své dlouhé dědictví proti takovým požadavkům na posun hardwaru, Gimp, libpng, Cairo atd. Alespoň cokoli, co představuje jazyk, se zdá, že nepředstavuje slepé uličky psát pár skvělých knihoven a produktů do kompetentních rukou, a to je opravdu vše, o co mě zajímá. Takže jsem nikdy nebyl typem, který by se zajímal o nejvášnivější jazykové války, kromě toho, abych pragmaticky apeloval a řekl: „Hej, je tu úžasné věci tam! Dozvěděme se, jak to zvládli, a možná existují skvělé lekce, které nejsou tak specifické pro idiomatickou povahu jazyka, že se můžeme vrátit zpět do jakéhokoli jazyka (jazyků), který používáme. “ :-D

0
Dragon Energy