Apakah C ++ tidak cocok untuk OOP? [Tutup]

12

Saya membaca di suatu tempat di salah satu jawaban untuk pertanyaan di sini (tidak ingat yang mana) bahwa C ++ tidak cocok untuk pemrograman berorientasi objek. Ada beberapa yang menyebutkan bahwa Anda dapat menggunakan fitur atau sesuatu seperti itu, tetapi tidak dalam arti OOP murni (saya sebenarnya tidak benar-benar mengerti apa yang dimaksud orang itu).

Apakah ada kebenaran dalam hal ini; jika demikian, mengapa?

Gablin
sumber
5
OOP bukan istilah yang terdefinisi dengan baik, jadi mendiskusikan apakah C ++ cocok atau tidak cocok, tidak ada gunanya.
zvrba

Jawaban:

31

Seperti yang dijelaskan di Jadi, apa * yang * Alan Kay maksud dengan istilah "berorientasi objek"? , Alan Kay berpikir bahwa penyampaian pesan adalah bagian penting dari OOP, tetapi sedikit yang tidak dimiliki oleh "C dengan kelas" (yang kemudian menjadi C ++). C ++ hanyalah struct dengan sedikit perilaku, sedangkan objek di Smalltalk atau Objective-C "cerdas" karena mereka dapat memutuskan apa yang mereka lakukan dengan pesan yang mereka kirim. Jika objek Smalltalk-esque menerima pesan yang tidak memiliki implementasinya, ia dapat dengan malas menambahkannya, meneruskan pesan ke objek lain, atau melakukan hal yang sewenang-wenang.

Apa yang ditawarkan C ++ dengan cara orientasi-objek adalah virtualmetode dan polimorfisme yang melibatkan cara metode-metode tersebut dipanggil. Ketika kompilator melihat tipe data (atau class) yang memiliki metode virtual, itu membangun vtable dengan slot untuk setiap metode virtual. Subkelas yang menerapkan metode virtual akan menempatkan implementasinya dalam slot yang benar, sehingga kode klien hanya perlu tahu di mana dalam tabel virtual untuk mencari kode yang akan dijalankan daripada menyelesaikannya sampai ke fungsi tertentu. Apakah ini berarti bahwa C ++ secara efektif memang memiliki bentuk pengiriman ganda, meskipun semuanya diimplementasikan dalam kompiler dan tidak mampu seperti sistem Smalltalk-esque.

Jika Anda menganggap penyampaian pesan sebagai hal mendasar bagi OOP, maka selagi Anda bisa melakukannya dengan C ++ itu jauh dari mudah. OTOH jika Anda menggunakan OOP untuk mengaitkan data dengan fungsi yang bekerja pada data itu, C ++ tidak masalah.

Komunitas
sumber
8
+1 - tetapi saya selalu menganggap panggilan fungsi adalah cara yang masuk akal untuk menyampaikan pesan. Benar, ini adalah fondasi tingkat rendah, bukan perbaikan tingkat tinggi untuk semuanya - tetapi pola objek aktif menunjukkan bahwa membangun dari fondasi itu dapat dilakukan.
Steve314
6
jadi ini tidak hanya berlaku untuk C ++, tetapi juga untuk Java, C #, Object Pascal, dll. Dan akhirnya adalah bahwa sistem pesan Windows API adalah apa yang Alan maksudkan sebagai hal terpenting dalam OOP, khususnya cara penanganannya oleh Delphi
Trinidad
@trinidad benar, kecuali C # sebenarnya mendukung resolusi dinamis. Saya berharap itu adil untuk mengatakan bahwa ide kami tentang OOP telah berubah dari waktu ke waktu untuk mengatasi kurangnya penyampaian pesan. Dibantu tidak diragukan oleh vendor mengatakan bahwa teknologi mereka pasti OOP dalam menghadapi bukti ...
@ steve314 ya itu. Memang itulah cara kerja ObjC, pengiriman pesan diterjemahkan menjadi panggilan fungsi yang mencari dan memanggil fungsi metode. Seperti yang saya pahami lewat pesan, pengiriman ganda itulah yang penting.
1
@ Paul: Memiliki pengalaman terbatas dengan API Win32, saya tidak mengerti. API apa pun yang objeknya berukuran variabel, dan jika perlu untuk pertama kalinya memanggil rutin untuk menentukan seberapa besar objek itu, mengalokasikan memori, dan menyebutnya lagi, gagal dalam pengujian kecantikan saya.
David Thornley
27

Diskusi semacam ini menggangguku karena kedengarannya seperti penafsiran, orang-orang memperdebatkan makna Kitab Suci, atau Konstitusi Amerika, dan apa arti penulis asli, seolah-olah apa yang kita pikir tidak penting.

Begini, Alan Kay adalah orang yang cerdas, dan dia punya ide bagus, yang berhadapan dengan banyak ide bagus lainnya, dan menemukan realisasinya dalam bahasa Smalltalk dan bahasa lainnya.

Dia bukan Mesias, dan OOP bukan Paradigma Pemrograman Sejati.

Itu adalah ide yang bagus, di antara banyak. Apakah C ++ memiliki ide bagus di dalamnya, berasal dari pola pikir OOP? Tentu saja.

Mike Dunlavey
sumber
8

C ++ mendukung OOP, jika Anda mendefinisikan OOP berarti enkapsulasi, pewarisan dan polimorfisme.

Namun, C ++ tidak benar-benar unggul di OOP. Salah satu alasannya adalah bahwa polimorfisme sering bergantung pada objek yang dialokasikan tumpukan, yang (walaupun menggunakan smart pointer), lebih alami untuk digunakan dalam bahasa yang dikumpulkan sampah.

Di mana C ++ unggul, bagaimanapun, adalah dalam pemrograman generik. C ++ memungkinkan Anda untuk dengan mudah membuat kode generik yang sangat efisien melalui teknik pemrograman fungsional berbasis template.

Charles Salvia
sumber
4

C ++ meminjam fitur OOP dari Simula. Satu atau lebih pengembang Simula IIRC berkomentar bahwa C ++ bukan yang mereka pikirkan.

C ++ memiliki alat yang bagus untuk abstraksi, tetapi lebih merupakan bahasa paradigma campuran daripada bahasa berorientasi objek. Fitur berorientasi objek ada di sana, tetapi Anda memiliki pilihan yang bukan "OOP ketat".

Salah satu "penyisih" nakal yang Anda dapatkan di C ++ adalah menggunakan metode mengikat lebih awal daripada terlambat. Tidak hanya ini mungkin - ini adalah standarnya. Di Jawa, "final" terkait, tetapi lebih bersih dalam beberapa hal (ini menentukan maksud dengan cara yang tidak hanya tentang menghindari overhead kinerja yang sepele), dan itu bukan default.

Dalam beberapa hal, C ++ menunjukkan tanda-tanda menjadi eksperimen awal yang masih ada di sini. Meski begitu, itu masih alat yang bagus, dengan banyak keuntungan yang tidak Anda dapatkan dalam bahasa OOP lainnya.

Steve314
sumber
2
C ++ memungkinkan non-OOP dan C ++ memungkinkan OOP, untuk beberapa bahasa menjadi OO harus mengizinkan OOP, oleh karena itu C ++ adalah bahasa OO.
Trinidad
1
Saya percaya Alan Kay, dari ketenaran Smalltalk, mengatakan C ++ bukan yang dia pikirkan ketika dia menciptakan istilah "berorientasi objek". Karena C ++ dimulai dengan "C with Classes", pencangkokan kelas Simula ke C, dan tidak pernah melakukan terobosan, tidak mengherankan bahwa ini terlihat seperti eksperimen awal.
David Thornley
1
@Trinidad: APAPUN bahasa memungkinkan OOP. Saya telah melihat cukup banyak kode OO yang bagus di C. lama yang lama. Ya, itu sakit mendefinisikan semua tabel metode virtual dengan tangan, tetapi bahasa jelas memungkinkannya .
Jan Hudec
4

Memaksa semuanya menjadi bagian dari kelas tidak selalu menghasilkan kode OO yang hebat.

Mintalah programmer prosedural yang buruk untuk memprogram di Jawa dan mereka mungkin akan mengambil kelas di suatu tempat, berikan metode utama statis dan tempelkan 1000 baris kode di dalamnya. Saya tahu saya telah melihatnya.

Java memiliki pernyataan switch. Saya telah melihat switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }dll di C ++ dan kode Java.

C ++ mendukung banyak konsep OO tetapi standarnya tidak ditentukan olehnya, namun saya kira banyak tergantung pada apa tujuan Anda.

Semantik "miskin" utama dalam C ++ adalah memungkinkan penyalinan konstruksi kelas-kelas di mana objek mentransmisikan ke objek lain. Anda dapat menonaktifkan ini tetapi kemudian Anda tidak dapat mengembalikannya dari suatu fungsi. Untungnya ini dibahas dalam C ++ 0x.

Uang tunai
sumber
3

OOP bukan hanya tentang memastikan semuanya dari atau berada di kelas. Sangat mungkin untuk menulis kode non-OO dalam bahasa "murni OO". Sebagai contoh, "main" sering ditunjukkan sebagai fungsi global, tetapi menciptakan kelas yang hanya berisi metode utama statis sama non-OO.

C ++ bekerja paling baik dengan campuran berbagai hal; ini seharusnya tidak mengejutkan, karena itulah cara sebagian besar hal terbaik bekerja terbaik. Seringkali OOP adalah salah satu alat yang sangat berguna.

Fred Nurk
sumber
2

C ++ dapat digunakan untuk OOP tetapi tidak semurni sesuatu seperti Smalltalk. C ++ juga memungkinkan Anda melakukan non-OOP yang mungkin dibicarakan orang.

Craig
sumber
2

Meskipun saya tidak setuju dengan sentimen, memang benar bahwa sistem tipe C ++ bukan murni OOP - bukan "semuanya adalah objek." Angka (khususnya) tidak dapat diperpanjang semudah mereka dalam, katakanlah, Smalltalk. Misalnya, Anda tidak dapat mendefinisikan kembali arti "2 + 2" (meskipun Anda dapat mendefinisikan kembali arti "dua + dua").

Tapi apa yang kebanyakan orang mungkin berarti adalah bahwa banyak orang menulis kode non-object oriented di C ++ tapi percaya bahwa karena mereka menggunakan "OOP" bahasa, mereka berorientasi objek. Itu tidak benar. Namun menurut pendapat saya, Anda dapat menulis kode imperatif mengerikan di Smalltalk dan tidak bisa lebih unggul dari desain OOP yang layak di C ++.

Larry OBrien
sumber
1

Keberatan Alan Kay untuk C ++ adalah bahwa itu adalah bahasa makro di atas C.

Gagasan "message passing" hanyalah gagasan bahwa instance kelas disimpan dalam memori dan bahwa mereka mengekspos metode yang dapat dipanggil. Pesan lewat * disimulasikan "dalam C ++ menggunakan vtables yang memegang pointer ke fungsi.

Untuk mengatakan bahwa pesan yang lewat tidak ada di C ++ tidak akurat, yang lebih akurat untuk mengatakan bahwa pesan yang lewat adalah bagian integral dari bahasa lain seperti smalltalk dan Java karena bahasa tersebut tidak memproses ulang konstruksi asing dan mencangkoknya pada C secara langsung.

Ini adalah argumen desain bahasa yang sangat semantik yang saya duga sedikit di luar tingkat pengalaman si penanya.

Yang sedang berkata ada seribu alasan untuk membenci C ++, dan sangat sedikit alasan untuk menyukainya.

Daripada mencari palu yang sempurna dan paku yang sempurna, temukan rumah yang sempurna untuk dibangun dan kemudian temukan alat yang tepat ... yang membutuhkan pengalaman.

Penting juga untuk diingat bahwa dalam pemrograman sistem, apa yang ditakutkan Alan Kay bukanlah "OOP murni" sebenarnya adalah kekuatan C ++. Untuk masing-masing ...

bobx
sumber
1
Objective C juga dimulai sebagai bahasa makro di atas C, tetapi merupakan bahasa yang berorientasi objek.
Jan Hudec
1

Dalam pandangan saya, ini bukan masalah definisi sebagai masalah kegunaan.

Objek adalah abstraksi yang dimaksudkan untuk membuatnya lebih mudah untuk membaca, menulis, dan alasan tentang program yang kompleks. Untuk seorang programmer praktis, apakah suatu bahasa memenuhi semua kriteria definisi formal tertentu "berorientasi objek" (tampaknya ada beberapa yang bersaing!) Tidak benar-benar sama pentingnya dengan apakah alat yang ditawarkannya cocok untuk dipikirkan. program Anda dalam hal objek yang dikatakan - yaitu, benar-benar menuai manfaat produktivitas yang seharusnya dari OOP.

Dalam C ++, objek adalah abstraksi yang sangat bocor , sering memaksa programmer untuk bertengkar dengan masalah-masalah buruk terkait dengan bagaimana objek-objek itu terstruktur dalam memori - masalah yang lebih mengingatkan pada pengkodean dalam C langsung daripada bahasa OOP lainnya. Misalnya, C ++ Jawaban yang Sering Diajukan menawarkan kritik ini (antara lain):

Sangat bermanfaat bagi seorang praktisi untuk mendapatkan keakraban dengan sistem OO selain C ++, dan dengan definisi OO selain traps "enkapsulasi, pewarisan, polimorfisme" yang ditafsirkan dengan cara khusus yang memungkinkan C ++ dianggap "OO". Misalnya, klaim bahwa lingkungan yang tidak memiliki pemeriksaan batas atau pengumpulan sampah bukanlah lingkungan OO yang terdengar keterlaluan bagi orang-orang yang terbiasa dengan C ++. Tetapi dari banyak perspektif, itu sangat masuk akal. Jika ada yang bisa menimpa objek, di mana "enkapsulasi"? Jika membuang objek dapat menyebabkan referensi menggantung atau kebocoran memori, bagaimana sistem "berorientasi objek" ? Bagaimana dengan kemampuan untuk mengetahui objek apa yang terletak di tempat dan waktu tertentu? Anda mengatakan perangkat lunak itu berfungsi dengan objek - di mana mereka? Dan jika seseorang tidak dapat mengetahuinya, bagaimana seseorang seharusnya melakukan debug pada perangkat lunak?

C ++ berorientasi objek, tetapi tidak menyenangkan dan tidak lengkap: penggunanya harus mencurahkan banyak upaya untuk memastikan data mereka benar-benar berperilaku seperti objek "nyata" daripada bit yang salah. Yang mengatakan, banyak kode telah ditulis dalam C + + selama masa pakainya, sebagian besar menggunakan kelas dan pengiriman dinamis, jadi itu jelas sesuatu yang dapat Anda gunakan untuk OOP praktis.

Alex P
sumber
-1 untuk referensi FQA dalam apa yang seharusnya menjadi jawaban serius. FQA adalah sarang distorsi, setengah kebenaran, dan kesalahpahaman.
David Thornley
@ Davidvidhorn Apakah kutipan tertentu distorsi, setengah-kebenaran, atau kesalahpahaman?
Alex P
Di suatu tempat di sana. Klaim bahwa bahasa OO harus memiliki pemeriksaan batas (kadang-kadang dibangun ke dalam wadah standar C ++) dan pengumpulan sampah (smart pointer adalah pengumpulan sampah primitif) dipaksa dan tidak jujur. Kalimat tentang bahasa yang memungkinkan referensi menggantung tidak berorientasi objek jelas Bukti oleh Pernyataan Blatant. Saya bingung dengan "kemampuan untuk mengatakan objek seperti apa"; tipe pointer memberikannya untuk objek tanpa perilaku virtual, dan RTTI menanganinya untuk objek dengan perilaku virtual.
David Thornley
@DavidThornley Klaim FQA adalah bahwa bahasa OO yang berguna harus memiliki hal-hal ini - yang sejalan dengan pertanyaan yang diajukan (apakah C ++ "cocok"?). Saya pikir klaim tentang definisi bare-tulang tidak benar-benar membahas bahwa ... "Kemampuan untuk mengatakan": perilaku kesalahan umum mengakses objek yang tidak benar-benar ada, dengan mengikuti pointer ke beberapa data yang tidak diinisialisasi atau yang sebelumnya ditimpa; dan program Anda akan dengan senang hati mengambil sampah itu dan menafsirkannya sebagai data, dan kemudian mengikuti petunjuk sampah ke data sampah lainnya sampai menyentuh alamat di luar batas atau beberapa kesalahan besar terjadi.
Alex P
Namun, kutipan setidaknya sangat menyarankan klaim bahwa bahasa tanpa pemeriksaan batas atau pengumpulan sampah bukan OO, dan mengabaikan fakta bahwa Anda memiliki hal-hal itu di C ++ jika Anda mau. Pertanyaan apakah suatu bahasa mencegah kelas kesalahan tertentu atau tidak (karena alasan apa pun) adalah ortogonal terhadap apakah bahasa itu OO.
David Thornley
-1

Ada alasan mengapa Graham Lee paling banyak mendapat dukungan di sini. Untuk mengulangi, tampaknya kelas C ++ tidak benar-benar objek dalam arti tidak melakukan passing pesan. Saya pikir inilah yang membuat banyak orang tersandung ketika mereka mempelajari C ++ atau oop. Orang-orang diberitahu bahwa berorientasi objek adalah 'ini' dan kemudian diberitahu bahwa C ++ melakukannya secara berbeda. Yah C ++ tidak pernah melakukan OOP secara berbeda. Jika Anda berpikir dengan cara ini Anda tidak akan pernah menghargai kelas C ++ untuk apa yang dimaksudkan untuk mereka dan itu adalah bahwa mereka hanya merupakan perbaikan paradigma prosedural dengan memasukkan abstraksi, dan perilaku dinamis. Jadi kelas-kelas C ++ pada dasarnya prosedural, mereka hanya meningkatkan paradigma prosedural, atau lebih tepatnya mereka adalah versi yang lebih maju dari sebuah struct C.

annoying_squid
sumber
Apakah Anda memiliki alasan pendukung aktual untuk argumen Anda? Anda tampaknya membuat pernyataan dan mengklaim bahwa mereka yang tidak setuju pasti salah, atau akan berubah pikiran jika mereka melihatnya secara berbeda, atau mungkin jika mereka memiliki definisi OO yang tepat.
David Thornley
Cukup adil. Anda dapat membaca artikel ini . Saya kira apa yang saya katakan adalah bahwa c ++ bukan "pemrograman berorientasi objek" dalam arti Alan Kay yang ketat. Namun jika Anda mendefinisikan OOP sebagai struktur data dengan perilaku maka Anda dapat menganggap c ++ sebagai OOP. Dalam pikiran saya meskipun lebih akurat untuk melihat kelas c ++ sebagai abstraksi pemrograman prosedural tingkat yang lebih tinggi. Kelas c ++ jauh lebih efisien daripada objek gaya Kay, tetapi lebih buruk untuk konkurensi. Secara pribadi saya pikir kelas c ++ adalah desain yang hebat.
annoying_squid
1
Terima kasih atas tautannya, tetapi itu hanya menjelaskan apa yang dimaksud Alan Kay. Selain itu, saya tidak setuju bahwa Smalltalk umumnya dianggap sebagai bahasa OO pertama, dan Wikipedia setuju dengan saya bahwa itu adalah Simula, salah satu dari dua bahasa yang digabungkan Stroustrup untuk membentuk C dengan Kelas. Saya tertarik pada klaim Anda bahwa kelas C ++ lebih merupakan abstraksi pemrograman prosedural tingkat yang lebih tinggi daripada templat objek, tapi saya masih tidak mengerti mengapa Anda berpikir seperti itu.
David Thornley
Orientasi Objek mungkin istilah subyektif, jika kita bisa menyetujuinya. Tapi saya melihat objek Kay sebagai cara yang lebih alami untuk memisahkan kode dan memperkenalkan modularitas bersamaan dalam arti bahwa setiap objek melayani peran seperti komputer mini yang berinteraksi melalui pengiriman pesan. Di bawah model ini perlu ada sedikit atau tidak ada kode 'di antara' b / c seluruh logika program dapat dinyatakan sebagai sel dan pesan. Dengan membandingkan penggunaan 'kelas' biasanya memerlukan beberapa kode lem prosedural di antara (tidak memiliki modularitas sejati) tetapi keuntungannya adalah bahwa kelas jauh lebih efisien.
annoying_squid
-1

Steve Yegge mengatakan yang terbaik :

C ++ adalah bahasa paling bodoh di dunia, dalam arti yang sebenarnya adalah yang paling tidak hidup. Itu tidak tahu tentang dirinya sendiri.

Sistem objek dalam C ++ sangat terprogram dan tetap pada waktu kompilasi, sehingga sangat jauh dari gagasan asli OOP yang melibatkan pesan-lewat, introspeksi, refleksi, pengiriman dinamis, dan pengikatan lambat, antara lain. Satu-satunya kesamaan C ++ dan Smalltalk adalah sedikit kosakata.

John Cromartie
sumber
Dengan cara apa C ++ bahasa yang paling tidak hidup? Apa artinya bahasa menjadi mahluk hidup? Jika Anda maksudnya tidak memiliki kemampuan refleksi, itu cukup umum, dan tentu saja tidak memilih C ++ dari kerumunan.
David Thornley
2
Bagaimana bisa kamu mengatakan bahwa dia mengatakan itu "terbaik"? Saya tidak tahu apa artinya kutipan acak itu.
user16764
+1 mengatakan hal semacam ini akan mendapatkan banyak kritik dari b + + basher bashers, tetapi harus dikatakan - Anda tidak dapat benar-benar OOP tanpa refleksi, karena Anda tidak memiliki obat generik untuk menangani hal-hal horisontal ( aspek) - siklus hidup (aktivasi, pembuangan), penanganan kesalahan umum, proksi generik, serialisasi generik, paralelisme tugas generik - ini pada akhirnya mencemari kode Anda dan memecah SoC.
vski
Terima kasih. Saya tidak percaya saya harus ke -3 karena mengatakan bahwa bahasa tanpa refleksi bukanlah contoh yang baik dari OOP.
John Cromartie
1
@ JohnCromartie, bisakah Anda menjelaskan hal itu dalam jawaban Anda?
Jeremy Heiler