it-swarm-tr.com

C'nin C ++ ile farkı nedir?

Birçok kişi C++ 'ın C'den tamamen farklı bir dil olduğunu söylemiş, ancak Bjarne kendisi C++' nın C'den genişletilmiş bir dil olduğunu ve bu nedenle ++ gelen. Peki neden herkes C ve C++ 'nın tamamen farklı diller olduğunu söylemeye devam ediyor? C, C++ 'daki genişletilmiş özellikler dışında C++' dan ne şekilde farklıdır?

21
Joshua Partogi

1980'lerde, C++ gelişimi henüz başladığında, C++ neredeyse C'nin uygun bir süper setiydi.
Bununla birlikte, zaman içinde hem C hem de C++ gelişti ve birbirinden ayrıldılar, ancak diller arasındaki uyumluluk her zaman önemli olarak kabul edildi.

Ayrıca, C ve C++ arasındaki teknik farklılıklar bu dillerdeki tipik deyimleri ve 'iyi uygulama' olarak kabul edilenleri daha da farklılaştırmıştır.

"C/C++ gibi bir dil yok" veya "C ve C++ iki farklı dildir" gibi şeyleri söyleyen insanların arkasındaki itici faktör budur. Hem C hem de C++ derleyicisi için kabul edilebilir programlar yazmak mümkün olsa da, kod genellikle ne iyi C kodu örneği ne de iyi C++ kodu örneği olarak kabul edilir.

18

Stroustrup'un kendisi SSS :

C++, C'nin neredeyse tamamını bir alt küme olarak tutan C'nin doğrudan torunudur. C++, C'den daha güçlü tip kontrolü sağlar ve C'den daha geniş bir programlama stilini doğrudan destekler. C++, C kullanarak daha iyi tip kontrolü ve daha notasyonel destek (kayıp olmadan) kullanılarak yapılan programlama stillerini desteklemesi açısından "daha iyi bir C" dir. verimlilik). Aynı anlamda, ANSI C, K&R C'den daha iyi bir C'dir. Ayrıca C++, veri soyutlamayı, nesne yönelimli programlamayı ve genel programlamayı destekler.

C++ 'dan C'ye "tamamen farklı" yapan nesne yönelimli programlama ve genel programlama desteği. Siz neredeyse saf C yazabilir ve daha sonra bir C++ derleyicisi (daha katı tür denetimine dikkat ettiğiniz sürece). Ama sonra hala C yazıyorsunuz - C++ yazmıyorsunuz.

C++ yazıyorsanız, nesne yönelimli ve şablon özelliklerini kullanıyorsunuz ve bu C'de gördüğünüz gibi bir şey değil.

20
Dean Harding

Basitçe söylemek gerekirse, C'de deyimsel olarak kabul edilen şey kesinlikle C++ 'da deyimsel değildir.

C ve C++, insanların bunları kullanma şekli nedeniyle pratikte çok farklı dillerdir. C, çok özelliklerle C++ 'ın çok karmaşık bir dil olduğu minimalizmi hedefler.

Bazı pratik farklılıklar da vardır: C hemen hemen her dilden kolayca çağrılabilir ve genellikle bir platformun ABI'sini tanımlar, oysa C++ 'ın diğer kütüphanelerden kullanımı oldukça zordur. Çoğu dilde C'de bir FFI veya arayüz bulunur, hatta C++ 'da uygulanan diller bile (örneğin Java).

13
David Cournapeau

C++ 'ın nesne yönelimli programlamayı desteklediği gerçeğinin yanı sıra, cevabınızı burada bulduğunuzu düşünüyorum: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++

Bu makalede, C, Tamam + C++ değil şeyler gösteren kod örnekleri içerir. Örneğin:

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

Bir C programının C++ 'a taşınması genellikle basittir ve çoğunlukla derleme hatalarının düzeltilmesinden oluşur (yayınlar, yeni anahtar kelimeler vb.).

4
Martin Wickman

C++, C'ye sadece yeni özellikler değil, yeni kavramlar ve yeni deyimler de ekler. C++ ve C yakından ilişkili olsa da, bir dilde etkili bir şekilde yazmak için o dilin tarzında düşünmeniz gerektiği gerçeği kalır. En iyi C kodu bile C++ 'nın farklı güçlü yönlerinden ve deyimlerinden yararlanamaz ve bu yüzden aslında kötü C++ kodundan daha olasıdır.

2
Jon Purdy

"Genişletilmiş özellikler", ses gibi ekledikleri C++ gibi, varyasyon makrolar ya da bir şey yapmak ve bu kadar. C++ 'daki "genişletilmiş özellikler", dilin bir tam revizyon ve en iyi C uygulamalarının yerini alır çünkü yeni C++ özellikleri orijinal C özelliklerinden tamamen daha iyidir ve orijinal C özelliklerinin tamamen büyük çoğunluk durumunda tamamen gereksiz. C++ 'ın sadece C'yi uzatmasını önermek, modern bir muharebe tankının savaşı sürdürmek için bir tereyağı avını uzatmasını öneriyor.

2
DeadMG

Aradaki fark, C'de yordamsal olarak ve C++ ile nesne yönelimli bir şekilde düşünmenizdir. Diller oldukça benzer, ancak yaklaşım çok farklı.

1
Ant

C++ sözdizimsel açıdan süper bir C kümesi olabilirken, yani C programının herhangi bir yapısı C++ derleyicisi tarafından derlenebilir.

Ancak, neredeyse hiçbir zaman bir C++ programını C programıyla yaptığınız gibi yazmazsınız. Liste sonsuz olabilir ya da birisi kapsamlı raporlar olarak koymak için daha fazla araştırma yapmalıdır. Ancak, önemli farklar yaratan birkaç işaretçi koyuyorum.

Şu anki gönderinin amacı, C++ 'ın iyi bir C++ programcısının C eşdeğeri derlemek mümkün olsa bile programlama en iyi uygulamaları olarak kullanması gereken aşağıdaki özelliklere sahip olmasıdır.

C++ 'da C üzerinden nasıl yapılmalı

  1. Sınıflar ve Kalıtım. Bu, programlama ifadesini çok güçlü kılan sistematik nesne yönlendirmesine izin veren en önemli farklardır. Sanırım - bu noktanın daha iyi bir açıklamaya ihtiyacı yok. C++ 'da iseniz - neredeyse her zaman, sınıfları kullanmak daha iyidir.

  2. Özelleştirme - Sınıflar ve hatta yapılar özel üyelere sahiptir. Bu, bir sınıfın kapsüllenmesini mümkün kılar. C'deki eşdeğeri, uygulamanın dahili değişkenlere erişimi olmaması için nesneyi uygulamaya void * olarak yazmaktır. Ancak, C++ 'da özel sınıfların yanı sıra genel sınıflara da sahip olabilirsiniz.

  3. Referans ile geçin. C++, geçen işaretçilerin gerekli olduğu referansa dayalı değişikliğe izin verir. Referans kodu, kodu çok temiz ve işaretçi tehlikelerine karşı daha güvenli tutar. Siz de bir geçiş C stili işaretçi ve bu işe yarıyor - ama C++ iseniz, sürece daha iyi

  4. yeni ve silme malloc ve ücretsiz. New () ve delete () ifadeleri yalnızca belleği ayırır ve ayırmayı kaldırmaz, aynı zamanda bir zincirde çağrılacak yıkıcıların bir parçası olarak kodun yürütülmesine izin verir. C++ kullanıyorsanız - aslında malloc ve free kullanmak KÖTÜdür.

  5. IO tipleri ve operatör aşırı yüklemesi Operatör aşırı yüklemesi, iyi yapılırsa kodu okunabilir veya daha sezgisel hale getirir. << ve >> io operatörleri için aynıdır. Bunu yapmanın C yolu işlev işaretçileri kullanmak olacaktır - ama dağınık ve sadece ileri düzey programcılar için.

  6. "String" kullanarak. C karakteri * her yerde çalışır. Yani C ve C++ hemen hemen aynı. Ancak, eğer C++ - her zaman çok daha iyi (ve daha güvenli) String sınıfları kullanmak neredeyse her şey olan diziler üzerinde çalışan tehlikelerden kurtaracak.

Özellikler Ben hala C++ hayranı olmazdı 1. Şablonlar - i birçok kod ağır şablonları kullanmazken - kütüphaneler için çok güçlü olduğu ortaya çıkabilir. C'de hemen hemen hiç eşdeğeri yoktur. Ama normal bir günde - özellikle matematiksel olarak eksik yapıyorsanız.

  1. Akıllı işaretçiler - Evet, çok akıllılar! Ve çoğu akıllı şey gibi - iyi başlıyorlar ve daha sonra dağınık hale geliyorlar! Kullanmaktan pek hoşlanmıyorum

C++ 'da beğendiğim ve C++' da özlediğim şeyler

  1. Fonksiyon göstergeleri kullanarak polimorfik algoritmalar. C'de, karmaşık algoritmalar çalıştırdığınızda - bazen fonksiyon işaretçileri kümesini kullanabilirsiniz. Bu güçlü polimorfizmi güçlü bir şekilde yapar. C++ 'da olduğunuzda [~ # ~] [~ # ~] işlev işaretçileri kullanabilirsiniz - ama bu kötüdür. Sadece yöntemleri kullanmalısınız - dağınık olmaya hazır olun. C++ sınıflarındaki polimorfizmin tek biçimi fonksiyon ve operatör aşırı yüklemesidir, ancak bu oldukça sınırlayıcıdır.

  2. Basit iplikler. Konuları pthreads oluşturduğunuzda - oldukça basit ve yönetilebilir. Sınıflara "özel" olması gereken iş parçacıkları oluşturmanız gerektiğinde olur (böylece özel üyelere erişebilirler). boost çerçeve türü vardır - ancak temel C++ 'da hiçbir şey yoktur.

Dipan.

0
Dipan Mehta

Bazı dil özellikleri, eklemeler olsa bile, dilin pratikte kullanılması gereken tüm yolu değiştirebilir. Örnek olarak bu durumu düşünün:

lock_mutex(&mutex);

// call some functions
...

unlock_mutex(&mutex);

Yukarıdaki kod, C++ 'da uygulanan işlevleri çağırmayı içeriyorsa, bu işlev çağrılarından herhangi biri atılabileceğinden ve bu istisnai yollardaki muteksin kilidini asla açmayacağımızdan, sorun dünyasına girebiliriz.

Yıkıcılar artık programcıların kaynakları o noktada serbest bırakmayı/serbest bırakmayı unutmamalarına yardımcı olmak için kolaylık alanında değiller. RAII pratik bir gereklilik haline gelir, çünkü önemsiz olmayan örneklerde atılabilecek her bir kod satırını tahmin etmek insanca mümkün değildir (bu satırların şimdi atmayabileceğini, ancak daha sonra değişikliklerle olabileceğini belirtmiyoruz). Başka bir örnek alın:

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

Bu kod, genellikle C'de zararsız olsa da, C++ 'da cehennem ateşini sallamak gibidir, çünkü memcpy bu nesnelerin bitleri ve baytları üzerinde buldozerler ve kopya yapıcılar gibi şeyleri atlar. memset, realloc, memcpy, vb. Gibi işlevler, C geliştiricileri arasındaki günlük araçlar, şeylere bellekte oldukça homojen bir bit ve bayt biçiminde bakarken kullanılır. C++ 'ın daha karmaşık ve daha zengin tip sistemiyle uyumlu değildir. C++, kullanıcı tanımlı türlerin çok daha soyut bir görünümünü teşvik eder.

Yani bu tür şeyler artık C++ 'ın doğru bir şekilde kullanmak isteyen herkesin C'nin sadece bir "süper yıldızı" olarak bakmasına izin vermiyor. Bu diller çok farklı bir zihniyet, disiplin ve en etkili şekilde kullanmak için düşünme biçimini gerektirir .

C++ 'ı her yönden daha iyi gören kampta değilim ve aslında en sevdiğim üçüncü taraf kütüphanelerinin çoğu nedense C kütüphaneleri. Neden tam olarak bilmiyorum ama C libleri doğada daha minimalist olma eğilimindedir (belki de bu kadar zengin bir tip sisteminin olmaması, geliştiricileri bazı büyük ve katmanlı soyutlamalar inşa etmeden gereken minimum işlevselliği sağlamaya daha fazla odakladığı için), ancak çoğunlukla kullanımlarımı basitleştirmek ve kullanımları için uyarlamak için etraflarına C++ sarmalayıcıları koymakla sonuçlanırım, ancak bunu yaparken bile minimalist doğa benim için tercih edilir. Minimalizmi, böyle nitelikleri aramak için fazladan zaman harcayanlar için bir kütüphanenin çekici bir özelliği olarak gerçekten seviyorum ve belki de C, sadece bu kadar büyük ve katmanlı ve soyut kodun bir C'de gelişecek gerçek PITA.

C++ 'dan çok sık tercih etmiyorum, ancak aslında C API'lerini en geniş ikili uyumluluk (ve FFI'ler için) için sık sık kullanmam gerekiyor, ancak başlıklar için C kullanmasına rağmen C++' da sık sık kullanıyorum. Ancak bazen bir bellek ayırıcısı veya çok düşük düzeyli veri yapısı gibi gerçekten düşük seviyeye gittiğinizde (ve gömülü programlama yapanlar arasında daha fazla örnek olduğundan eminim), bazen birlikte çalıştığınız türlerin ve verilerin vtables, costructors ve destructors gibi belirli özellikleri olmadığını varsayabiliriz, böylece onları karıştırmak, kopyalamak, serbest bırakmak, yeniden tahsis etmek için bit ve bayt olarak ele alabiliriz. Çok düşük seviyeli problemler için, bazen C'nin sağladığı çok daha basit bir tip sistemle çalışmak faydalı olabilir ve elbette daha hızlı ve daha ileri inşa etme eğilimindedir.

Bir Açıklama

Burada ilginç bir yorum biraz daha derinlemesine yanıt vermek istedim (Buradaki yorumların karakter sınırında çok katı olduğunu düşünüyorum):

memcpy(&f2, f1, sizeof f2);, Foo'nun kendine ait işaretçileri varsa veya daha da kötüsü, bununla başa çıkacak araçlardan yoksun olduğunuzda, C'de "cehennem ateşi hüküm sürüyor".

Bu adil bir nokta ama odaklandığım her şey ağırlıklı olarak C++ 'ın tip sistemine ve RAII'ye odaklanıyor. Bu tür x-ışını bayt kopyalama memcpy veya qsort işlev türlerinin C'de daha az pratik tehlike oluşturmasının nedenlerinden biri, f1 Ve f2 Açıktır (önemsiz olmayan yıkıma ihtiyaç duyuyorlarsa bile), yıkıcılar resme geçtiğinde, örtük ve otomatik hale gelirler (genellikle geliştiricilere büyük değer verir). Bu, vptrs ve benzeri gibi gizli durumdan bile bahsetmez, bu tür işlevler hemen buldozer. f1 İşaretçiler varsa ve f2 Sığ bazı geçici bağlamlarda kopyalarsa, bu sahip olan işaretçileri ikinci kez serbest bırakmaya çalışmazsak sorun olmaz. C++ ile bu derleyicinin otomatik olarak yapmak isteyeceği bir şeydir.

Ve bu genellikle daha büyük olursa genellikle C, " Eğer Foo'nun işaretçileri var ", çünkü kaynak yönetiminde gereken açıklık genellikle göz ardı edilmesini genellikle daha zor hale getirecekken, C++ 'da bir UDT'yi artık sadece herhangi bir üye değişkeni depolayarak önemsiz bir şekilde inşa edilemez/yıkılamaz hale getirebiliriz. t Önemsiz bir şekilde inşa edilebilir/yıkılabilir (yine çok yararlı bir şekilde, ama memcpy veya realloc gibi fonksiyonları kullanmaya eğilimliysek değil).

Benim asıl amacım bu açıklığın herhangi bir faydasını tartışmaya çalışmak değil (eğer varsa, neredeyse her zaman onunla birlikte gelen insan hatası olasılığının eksileri tarafından tartılır), ama sadece söylemek gerekirse memcpy ve memmove ve qsort ve memset ve realloc gibi işlevlerin UDT'lerin zengin olduğu bir dilde yeri yoktur C++ gibi özellikler ve yetenekler. Ne olursa olsun var olsalar da, C++ geliştiricilerinin büyük, büyük çoğunluğunun veba gibi işlevlerden kaçınmanın akıllıca olacağını söylemek çok çekişmeli olmayacak, oysa bunlar C'deki çok günlük işlevler ve ben ' d, tip sisteminin çok daha basit ve belki de "dumber" olmasının basit bir nedeni olarak C'de daha az sorun yaşadıklarını iddia ederler. X-ışını C tipleri ve bunları bit ve bayt olarak işlemek hataya açıktır. C++ 'da bunu yapmak kesinlikle yanlıştır, çünkü bu tür işlevler dilin çok temel özelliklerine ve yazı sisteminin teşvik ettiği şeylere karşı savaşır.

Bu aslında C'nin benim için en büyük cazibesi, özellikle de dilin birlikte çalışabilirliği ile nasıl ilişkili olduğu. C++ 'ın FFI gibi bir şeyi yapıcılara, yıkıcılara, istisnalara, sanal işlevlere, işlev/yöntem aşırı yüklemesi, operatör aşırı yüklemesi, tüm çeşitli tiplere kadar C++' ın tam gelişmiş tip sistemini ve dil özelliklerini anlaması çok, çok daha zor olurdu. C ile, birçok farklı dilin doğrudan FFI'ler aracılığıyla veya dolaylı olarak bazı C API dışa aktarma işlevleri aracılığıyla istenen bir biçimde içe aktarabileceği şekilde API'lara kadar standart hale gelen nispeten kalın bir dildir (ör: Java Native Interface) .Bu, çoğunlukla C'yi kullanmaktan başka seçeneğim kalmadı, çünkü bu dil birlikte çalışabilirliği bizim durumumuzda pratik bir gerekliliktir (çoğu zaman sadece C++ ile C arayüzleri yazıyorum) arkasındaki uygulamalar).

Ama biliyorsun, ben bir pragmatistim (ya da en azından olmaya çalışıyorum). C, bu en kötü ve godawful, hataya açık, kötü bir dil olsaydı, C++ meraklı akranlarımdan bazıları bunu iddia etti (ve bir şekilde benim tarafımda C nefretine yol açmaması dışında kendimi bir C++ meraklısı olarak sayacaktım Aksine, her iki dili de kendi açılarından ve farklılıklarından daha iyi takdir etmeme karşı ters bir etki yarattı), o zaman gerçek dünyada en ürkütücü ve en sızıntılı bazı formlarda görünmesini beklerdim ve C dilinde yazılmış güvenilir olmayan ürünler ve kütüphaneler. Linux'u seviyorum, Apache, Lua, zlib'i seviyorum, OpenGL'yi bu tür değişen donanım gereksinimlerine, Gimp, libpng, Kahire, vb.'ye karşı uzun mirası için tolere edilebilir buluyorum. En azından dilin ortaya koyduğu engeller, Bazı harika kütüphaneler ve ürünleri yetkin ellerde yazıyorum ve gerçekten ilgilendiğim tek şey bu. Bu yüzden pragmatik bir çekicilik yapmak ve "Hey, orada Nasıl başardıklarını öğrenelim ve belki de dilin deyimsel doğasına o kadar özel olmayan, kullandığımız dil (ler) e geri getirebileceğimiz harika dersler var. " :-D

0
Dragon Energy