it-swarm-id.com

Bagaimana C berbeda dari C ++?

Banyak orang mengatakan bahwa C++ adalah bahasa yang sama sekali berbeda dari C, tetapi Bjarne sendiri mengatakan bahwa C++ adalah bahasa yang diperluas dari C maka dari situlah ++ datang dari. Jadi mengapa semua orang terus mengatakan bahwa C dan C++ adalah bahasa yang sama sekali berbeda? Dalam hal apa C berbeda dari C++ selain fitur yang diperluas dalam C++?

21
Joshua Partogi

Selama tahun 1980-an, ketika pengembangan C++ baru saja dimulai, C++ hampir merupakan superset dari C. Itulah awal mulanya.
Namun, seiring berjalannya waktu, baik C dan C++ berevolusi dan telah menyimpang satu sama lain, meskipun kompatibilitas antara bahasa selalu dianggap penting.

Selain itu, perbedaan teknis antara C dan C++ telah membuat idiom khas dalam bahasa-bahasa tersebut dan apa yang dianggap sebagai 'praktik yang baik' semakin berbeda.

Ini adalah faktor pendorong di belakang orang mengatakan hal-hal seperti "tidak ada bahasa seperti C/C++" atau "C dan C++ adalah dua bahasa yang berbeda". Meskipun dimungkinkan untuk menulis program yang dapat diterima oleh kompiler C dan C++, kode ini umumnya dianggap bukan contoh dari kode C yang baik atau contoh dari kode C++ yang baik.

18

Stroustrup sendiri menjawab itu di FAQ-nya :

C++ adalah turunan langsung dari C yang mempertahankan hampir semua C sebagai himpunan bagian. C++ memberikan pengecekan tipe yang lebih kuat daripada C dan secara langsung mendukung rentang gaya pemrograman yang lebih luas daripada C. C++ adalah "C yang lebih baik" dalam arti mendukung C gaya pemrograman yang dilakukan menggunakan C dengan pengecekan tipe yang lebih baik dan lebih banyak dukungan notasi (tanpa kehilangan efisiensi). Dalam pengertian yang sama, ANSI C adalah C yang lebih baik daripada K&R C. Selain itu, C++ mendukung abstraksi data, pemrograman berorientasi objek, dan pemrograman generik.

Ini mendukung pemrograman berorientasi objek dan pemrograman generik yang membuat C++ "sangat berbeda" dengan C. Anda dapat hampir menulis C murni dan kemudian mengompilasinya dengan Kompiler C++ (selama Anda menangani pengecekan tipe yang lebih ketat). Tapi kemudian Anda masih menulis C - Anda tidak menulis C++.

Jika Anda sedang menulis C++, maka Anda memanfaatkannya berorientasi objek dan fitur template dan itu tidak seperti apa yang akan Anda lihat di C.

20
Dean Harding

Sederhananya, apa yang dianggap idiomatik dalam C jelas bukan idiomatik dalam C++.

C dan C++ adalah bahasa yang sangat berbeda dalam praktiknya, karena cara orang menggunakannya. C bertujuan untuk minimalisme, di mana C++ adalah bahasa yang sangat kompleks, dengan banyak fitur.

Ada juga beberapa perbedaan praktis: C dapat dengan mudah dipanggil dari hampir semua bahasa, dan sering mendefinisikan ABI platform, sedangkan C++ cukup sulit digunakan dari perpustakaan lain. Sebagian besar bahasa memiliki FFI atau antarmuka dalam C, bahkan bahasa diimplementasikan dalam C++ (Java, misalnya).

13
David Cournapeau

Terlepas dari fakta yang jelas bahwa C++ mendukung pemrograman berorientasi objek, saya pikir Anda punya jawaban di sini: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++

Artikel itu berisi contoh kode yang menunjukkan hal-hal yang ok di C tetapi tidak di C++. Contohnya:

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

Porting program C ke C++ seringkali langsung dan sebagian besar terdiri dari memperbaiki kesalahan kompilasi (menambahkan gips, kata kunci baru dll).

4
Martin Wickman

C++ tidak hanya menambahkan fitur-fitur baru, tetapi juga konsep-konsep baru dan idiom-idiom baru pada C. Meskipun C++ dan C saling berkaitan, faktanya tetap bahwa untuk menulis secara efektif dalam suatu bahasa, Anda harus berpikir dengan gaya bahasa itu. Bahkan kode C terbaik tidak dapat mengambil keuntungan dari kekuatan dan idiom yang berbeda dari C++, dan karena itu lebih mungkin daripada tidak sebenarnya --- buruk kode C++.

2
Jon Purdy

"Fitur yang diperluas", Anda membuatnya terdengar seperti di C++ yang mereka tambahkan seperti, makro variadic atau sesuatu dan hanya itu. "Fitur yang diperluas" di C++ adalah perombakan total bahasa dan benar-benar menggantikan praktik C terbaik karena fitur C++ baru jauh lebih baik daripada fitur C asli sehingga fitur C asli sepenuhnya dan benar-benar berlebihan dalam sebagian besar kasus. Menyarankan bahwa C++ hanya memperluas C berarti bahwa tank tempur modern memperluas pisau lipat untuk keperluan berperang.

2
DeadMG

Perbedaannya adalah bahwa dalam C Anda berpikir secara prosedural dan dalam C++ Anda berpikir dalam cara yang berorientasi objek. Bahasanya sangat mirip tetapi pendekatannya sangat berbeda.

1
Ant

Sementara C++ dapat menjadi set super C dalam istilah sintaksis - yaitu setiap konstruk program C dapat dikompilasi oleh kompiler C++.

Namun, Anda hampir tidak pernah menulis program C++ seperti yang Anda lakukan dengan program C. Daftar itu bisa tak ada habisnya atau mungkin seseorang harus melakukan penelitian lebih lanjut untuk menempatkannya sebagai laporan lengkap. Namun, saya menempatkan beberapa petunjuk yang membuat perbedaan utama.

Inti dari postingan saat ini adalah bahwa C++ memiliki fitur berikut yang harus digunakan oleh programmer C++ yang baik sebagai pemrograman praktik terbaik meskipun C yang setara dimungkinkan untuk dikompilasi.

Bagaimana seharusnya dilakukan dalam C++ over C

  1. Kelas & Waris. Itulah perbedaan paling penting yang memungkinkan orientasi objek sistematis yang membuat ekspresi pemrograman sangat kuat. Saya kira - poin ini tidak perlu penjelasan yang lebih baik. Jika Anda menggunakan C++ - hampir selalu, Anda lebih baik memanfaatkan kelas.

  2. Privatisasi - Kelas, dan bahkan struktur memiliki apa yang anggota pribadi. Ini memungkinkan enkapsulasi kelas. Setara dalam C adalah dengan cara typecasting objek sebagai void * ke aplikasi sehingga aplikasi tidak memiliki akses ke variabel internal. Namun, di C++ Anda dapat memiliki elemen dengan kelas publik dan swasta.

  3. Lewati dengan referensi. C++ memungkinkan modifikasi berdasarkan referensi, untuk itu diperlukan pointer yang lewat. Pass-by-reference menjaga kode tetap bersih dan lebih aman terhadap bahaya pointer. Anda juga lulus gaya C pointer dan itu berfungsi - tetapi jika Anda berada di C++ Anda lebih baik selama

  4. baru & hapus vs. malloc dan gratis. Pernyataan baru () dan hapus () tidak hanya mengalokasikan dan mendelegasikan memori, tetapi juga memungkinkan kode untuk dieksekusi sebagai bagian dari destruct-er dipanggil dalam sebuah rantai. Jika Anda menggunakan C++ - sebenarnya buruk untuk menggunakan malloc dan gratis.

  5. Tipe IO dan overloading operator Overloading operator membuat kode dapat dibaca atau lebih intuitif jika dilakukan dengan baik. Sama untuk operator << dan >> io. Cara C melakukan ini adalah dengan menggunakan pointer fungsi - tetapi itu berantakan dan hanya untuk programmer yang sudah mahir.

  6. Menggunakan "string". Char * dari C bekerja di mana-mana. Jadi C dan C++ hampir sama. Namun, jika Anda menggunakan C++ - selalu lebih baik (dan lebih aman) untuk menggunakan kelas-kelas String yang menyelamatkan Anda dari bahaya array saat menjalankan yang hampir semuanya.

Fitur yang saya masih belum menjadi penggemar di C++ 1. Templates - Walaupun saya tidak menggunakan template yang berat dalam banyak kode - ini bisa berubah menjadi sangat kuat untuk perpustakaan. Hampir tidak ada yang setara dengan itu di C. Tetapi pada hari normal - khususnya jika Anda melakukan matematis yang hilang.

  1. Pointer pintar - Ya, mereka sangat pintar! Dan seperti kebanyakan hal cerdas - mereka memulai dengan baik dan menjadi berantakan nantinya! Saya tidak suka menggunakannya

Hal-hal yang saya sukai tentang C dan ketinggalan dalam C++

  1. Algoritma polimorfik dengan menggunakan pointer fungsi. Di C, ketika Anda menjalankan algoritma yang kompleks - beberapa kali Anda dapat menggunakan set pointer fungsi. Ini membuat polimorfisme benar dengan sangat kuat. Ketika Anda berada di C++ Anda [~ # ~] dapat [~ # ~] menggunakan pointer fungsi - tetapi itu buruk. Anda seharusnya hanya menggunakan metode - jika tidak bersiaplah untuk menjadi berantakan. Satu-satunya bentuk polimorfisme di kelas C++ adalah fungsi dan operator kelebihan tetapi itu cukup membatasi.

  2. Utas sederhana. Ketika Anda membuat utas adalah pthreads - ini cukup sederhana dan dapat dikelola. Menjadi ketika Anda perlu membuat utas yang seharusnya "pribadi" untuk kelas (sehingga mereka memiliki akses ke anggota pribadi). Ada boost jenis kerangka kerja - tetapi tidak ada dalam C++ dasar.

Dipan.

0
Dipan Mehta

Fitur bahasa tertentu, bahkan jika itu adalah tambahan, dapat mengubah keseluruhan cara bahasa praktis perlu digunakan. Sebagai satu contoh, pertimbangkan kasus ini:

lock_mutex(&mutex);

// call some functions
...

unlock_mutex(&mutex);

Jika kode di atas melibatkan fungsi pemanggilan yang diimplementasikan dalam C++, kita mungkin berada dalam masalah, karena salah satu dari pemanggilan fungsi itu mungkin muncul dan kita tidak akan pernah membuka kunci di jalur luar biasa tersebut.

Destructors tidak lagi dalam bidang kenyamanan untuk membantu programmer menghindari lupa untuk melepaskan/sumber daya gratis pada saat itu. RAII menjadi persyaratan praktis karena tidak layak secara manusiawi untuk mengantisipasi setiap baris kode yang dapat memberikan contoh-contoh non-sepele (belum lagi bahwa baris-baris itu mungkin tidak dibuang sekarang tetapi mungkin nanti dengan perubahan). Ambil contoh lain:

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

Kode seperti itu, walaupun umumnya tidak berbahaya di C, seperti api neraka yang menguasai kekacauan di C++, karena memcpy melibas bit dan byte dari objek-objek ini dan memintas hal-hal seperti copy constructor. Fungsi seperti memset, realloc, memcpy, dll, sedangkan alat harian di antara pengembang C yang digunakan untuk melihat hal-hal dengan cara yang agak homogen dari bit dan byte dalam memori, adalah tidak serasi dengan sistem tipe C++ yang lebih kompleks dan lebih kaya. C++ mendorong tampilan yang lebih abstrak dari tipe yang ditentukan pengguna.

Jadi hal-hal semacam ini tidak lagi memungkinkan untuk C++, oleh siapa pun yang ingin menggunakannya dengan benar, untuk melihatnya sebagai "superset" belaka dari C. Bahasa-bahasa ini membutuhkan pola pikir, disiplin, dan cara berpikir yang sangat berbeda untuk menggunakan yang paling efektif .

Saya tidak berada di kamp yang melihat C++ sebagai lebih baik dalam segala hal, dan sebenarnya sebagian besar lib pihak ketiga favorit saya adalah perpustakaan C untuk beberapa alasan. Saya tidak tahu persis mengapa tetapi lib C cenderung lebih minimalis di alam (mungkin karena tidak adanya sistem tipe kaya membuat pengembang lebih fokus pada menyediakan fungsionalitas minimal yang diperlukan tanpa membangun beberapa abstraksi yang besar dan berlapis), meskipun saya sering berakhir hanya menempatkan pembungkus C++ di sekitar mereka untuk menyederhanakan dan menyesuaikan penggunaannya untuk tujuan saya, tetapi sifat minimalis lebih disukai bagi saya bahkan ketika melakukan itu. Saya benar-benar menyukai minimalis sebagai fitur yang menarik dari perpustakaan bagi mereka yang menggunakan waktu ekstra untuk mencari kualitas seperti itu, dan mungkin C cenderung mendorong itu, jika hanya berdasarkan fakta bahwa kode besar dan berlapis serta abstrak seperti itu akan menjadi PITA nyata untuk dikembangkan dalam C.

Saya menyukai C++ jauh lebih sering daripada tidak, tapi saya sebenarnya diharuskan untuk menggunakan API C lebih sering untuk kompatibilitas biner terluas (dan untuk FFI), meskipun saya sering mengimplementasikannya dalam C++ meskipun menggunakan C untuk header. Tapi kadang-kadang ketika Anda pergi tingkat yang sangat rendah, seperti ke tingkat pengalokasi memori atau struktur data tingkat yang sangat rendah (dan saya yakin ada contoh lebih lanjut di antara mereka yang melakukan pemrograman tertanam), kadang-kadang bisa membantu untuk menjadi dapat berasumsi bahwa tipe dan data yang Anda kerjakan tidak ada fitur tertentu seperti vtables, costructors, dan destructor, sehingga kami dapat memperlakukannya sebagai bit dan byte untuk diacak, disalin, bebaskan, realokasi. Untuk masalah tingkat rendah yang sangat khusus, kadang-kadang bisa membantu untuk bekerja dengan sistem tipe yang jauh lebih sederhana yang disediakan C, dan tentu saja cenderung untuk membangun lebih cepat dan sebagainya.

Klarifikasi A

Satu komentar menarik di sini saya ingin menanggapi sedikit lebih mendalam (saya menemukan komentar di sini sangat ketat pada batas karakter):

memcpy(&f2, f1, sizeof f2); juga "hellfire reaving malapetaka" di C jika Foo memiliki pointer yang memiliki, atau bahkan lebih buruk, karena Anda juga tidak memiliki alat untuk menghadapinya.

Itu poin yang adil tetapi semua yang saya fokuskan terutama dengan fokus pada sistem tipe C++ dan juga sehubungan dengan RAII. Salah satu alasan mengapa x-rayish byte-copying memcpy atau qsort jenis fungsi tidak terlalu berbahaya bagi C adalah karena penghancuran f1 Dan f2 Di atas adalah eksplisit (jika mereka bahkan membutuhkan kehancuran non-sepele), sedangkan ketika destructor bergerak ke dalam gambar, mereka menjadi implisit dan otomatis (seringkali dengan nilai besar bagi para pengembang). Itu belum lagi keadaan tersembunyi seperti vptrs dan sebagainya yang fungsi-fungsi seperti itu akan melibas. Jika f1 Memiliki pointer dan f2 Akan menyalinnya dalam beberapa konteks sementara, maka itu tidak menimbulkan masalah jika kita tidak mencoba untuk secara eksplisit membebaskan pointer yang memiliki pointer tersebut untuk kedua kalinya. Dengan C++ itu adalah sesuatu yang secara otomatis ingin dilakukan oleh kompiler.

Dan itu menjadi lebih besar if biasanya dalam C, " If Foo memiliki petunjuk ", karena saksi yang diperlukan dengan manajemen sumber daya akan sering membuat sesuatu yang biasanya lebih sulit untuk diabaikan sedangkan di C++, kita dapat membuat UDT tidak lagi dapat dibangun/diremehkan dengan hanya membuatnya menyimpan variabel anggota mana pun yang bukan t sepele dibangun/dirusak (dengan cara yang umumnya sangat membantu, sekali lagi, tetapi tidak jika kita tergoda untuk menggunakan fungsi seperti memcpy atau realloc).

Poin utama saya adalah untuk tidak mencoba memperdebatkan manfaat dari kesaksian ini (saya akan mengatakan jika ada, mereka hampir selalu terbebani oleh kontra meningkatnya kemungkinan kesalahan manusia yang menyertainya), tetapi hanya untuk mengatakan bahwa fungsi seperti memcpy dan memmove dan qsort dan memset dan realloc dan sebagainya tidak memiliki tempat dalam bahasa dengan UDT yang kaya fitur dan kemampuan sebagai C++. Meskipun mereka ada, saya pikir tidak akan terlalu diperdebatkan untuk mengatakan bahwa sebagian besar, pengembang C++ yang luas akan bijaksana untuk menghindari fungsi seperti wabah, sedangkan ini adalah jenis fungsi yang sangat harian di C, dan saya d berpendapat bahwa mereka menimbulkan lebih sedikit masalah dalam C karena alasan sederhana bahwa sistem tipenya jauh lebih mendasar dan, mungkin "bodoh". Tipe C sinar-X dan memperlakukannya sebagai bit dan byte rentan kesalahan. Melakukan hal itu di C++ bisa dibilang keliru karena fungsi-fungsi tersebut berjuang melawan fitur yang sangat mendasar dari bahasa dan apa yang mendorongnya dari sistem tipe.

Itu sebenarnya daya tarik terbesar bagi saya C, bagaimanapun, khususnya dengan bagaimana hal itu terkait dengan interoperabilitas bahasa. Akan jauh, jauh lebih sulit untuk membuat sesuatu seperti C #'s FFI memahami sistem tipe penuh dan fitur bahasa C++ turun ke konstruktor, destruktor, pengecualian, fungsi virtual, kelebihan fungsi/metode, kelebihan operator, kelebihan semua jenis pewarisan, dll. Dengan C itu adalah bahasa yang relatif bodoh yang telah menjadi agak standar sejauh API dengan cara yang banyak bahasa dapat impor langsung melalui FFI, atau secara tidak langsung melalui beberapa fungsi ekspor API C dalam bentuk yang diinginkan (mis: Java Antarmuka Asli). Dan di situlah saya kebanyakan tidak punya pilihan selain menggunakan C, karena interoperabilitas bahasa adalah persyaratan praktis dalam kasus kami (meskipun sering saya hanya menulis antarmuka C dengan C++ implementasi di belakang mereka).

Tapi tahukah Anda, saya seorang pragmatis (atau setidaknya saya berusaha keras untuk menjadi). Jika C adalah bahasa yang paling kotor dan mengerikan, rawan kesalahan, dan jahat, beberapa rekan penggila C++ saya mengklaimnya (dan saya menganggap diri saya penggemar C++ kecuali bahwa entah bagaimana itu tidak mengarah pada kebencian C di pihak saya. ; sebaliknya itu memiliki efek sebaliknya pada saya untuk membuat saya menghargai kedua bahasa lebih baik dalam hal dan perbedaan mereka sendiri), maka saya berharap itu muncul di dunia nyata dalam bentuk beberapa buggiest dan leakiest dan produk dan perpustakaan yang tidak dapat diandalkan ditulis dalam C. Dan saya tidak menemukan itu. Saya suka Linux, saya suka Apache, Lua, zlib, saya menemukan OpenGL dapat ditoleransi karena warisannya yang panjang terhadap persyaratan perangkat keras yang berubah, Gimp, libpng, Kairo, dll. Setidaknya rintangan apa pun yang ditimbulkan oleh pose bahasa tampaknya tidak menimbulkan hambatan sejauh menulis beberapa perpustakaan dan produk keren di tangan yang kompeten, dan itu benar-benar yang saya minati. Jadi saya belum pernah menjadi tipe yang begitu tertarik dengan perang bahasa yang paling bersemangat, kecuali untuk membuat daya tarik pragmatis dan berkata, "Hei, ada hal-hal keren di luar sana! Mari kita pelajari bagaimana mereka membuatnya dan mungkin ada pelajaran yang keren, tidak begitu spesifik dengan sifat bahasa yang idiomatis, yang bisa kita bawa kembali ke bahasa apa pun yang kita gunakan. " :-D

0
Dragon Energy