C ++ OOP için uygun değil mi? [kapalı]


12

Burada bir sorunun cevabında bir yerde okudum (hangisini hatırlayamıyorum) C ++ 'ın nesne yönelimli programlama için uygun olmadığını. Özelliklerinden veya bunun gibi bir şeyden yararlanabileceğinizden bahsedenler vardı, ama tamamen OOP anlamda değil (aslında kişinin ne anlama geldiğini gerçekten anlamadım).

Bunda bir gerçek var mı; Öyleyse neden?



5
OOP iyi tanımlanmış bir terim değildir, bu nedenle C ++ 'ın uygun olup olmadığını tartışmak anlamsızdır.
zvrba

Yanıtlar:


31

" Alan Kay" gerçekten "nesne yönelimli" terimi ile ne demek istiyordu? , Alan Kay, mesaj geçişinin OOP'un önemli bir parçası olduğunu düşündü, ancak "sınıflarla C" nin (daha sonra C ++ oldu) eksik olduğu biraz. C ++ sadece biraz davranış içeren yapılardır, oysa Smalltalk veya Objective-C'deki nesneler gönderildikleri mesajlarla ne yapacaklarına karar verebilmeleri için "akıllıdır". Bir Smalltalk-esque nesnesi, uygulaması olmayan bir ileti alırsa, tembel olarak bir tane ekleyebilir, iletiyi başka bir nesneye iletebilir veya herhangi bir keyfi şey yapabilir.

C ++ 'ın nesne yönelimi yolunda sunduğu şey virtual, bu yöntemlerin çağrılma şeklini içeren yöntemler ve polimorfizmdir. Derleyici class, sanal yöntemleri olan bir veri türü (veya ) gördüğünde, her sanal yöntem için bir yuvalı bir vtable oluşturur. Sanal yöntemleri uygulayan alt sınıflar, uygulamalarını doğru yuvalara koyacaktır, bu nedenle istemci kodunun, yalnızca belirli bir işleve kadar çözülmek yerine kodun çalışmasını aramak için sanal tablonun neresinde çalışacağını bilmesi gerekir. Bu ne anlama geliyor etkili bir ++ o C does hepsi derleyici uygulanan ve bir Smalltalk-vari bir sistem olarak yetenekli olarak değil mi rağmen, çoklu sevkinden bir form var.

İleti iletmeyi OOP için temel olarak alırsanız , o zaman C ++ ile yapabiliyorsanız bu çok kolay değildir. OTOH, verileri bu veriler üzerinde etkili işlevlerle ilişkilendirmek anlamına gelirse, C ++ iyidir.


8
+1 - ama her zaman bir işlev çağrısının yine de bir mesaj iletmenin makul bir yolu olduğunu düşündüm. Doğru, bu her şey için yüksek seviye bir düzeltme yerine düşük seviyeli bir temeldir - ancak aktif nesneler deseni bu temelden oluşturulabilir olduğunu gösterir.
Steve314

6
bu nedenle bu durum sadece C ++, ancak vb Java, C #, Object Pascal, Ve Windows API mesajlaşma sistemi Alan OOP en önemli şey olarak ne anlama geldiğini olduğunu olmak biter o Delphi tarafından ele alınır özel bir şekilde
Trinidad

@trinidad doğru, ancak C # dinamik çözünürlüğü desteklemiyor. OOP fikrimizin zaman içinde mesaj geçişi eksikliği etrafında değiştiğini söylemek doğru olur. Şüphesiz, teknolojilerinin kanıt karşısında kesinlikle OOP olduğunu söyleyen satıcılar tarafından yardımcı oldu ...

@ steve314 evet öyle. Gerçekten de ObjC bu şekilde çalışır, bir mesaj gönderme işlevi arayan ve yöntem fonksiyonunu çağıran bir fonksiyon çağrısına çevrilir. İleti aktarmayı anladığım kadarıyla, önemli olan çift gönderimdir.

1
@Paul: Win32 API ile sınırlı bir deneyime sahip, anlamıyorum. Nesnelerin değişken boyutta olduğu ve nesnenin ne kadar büyük olacağını belirlemek için bir rutini çağırmanın, belleği tahsis etmenin ve tekrar çağırmanın gerekli olduğu herhangi bir API, güzellik testimde başarısız olur.
David Thornley

27

Tartışma huzursuzluktur beni Bu tür insanların Kutsal Scriptute, ya da Amerikan Anayasası ve anlamını tartışıyor, tefsir gibi geliyor çünkü neyi asıl yazar demek (ler) ne sanki biz düşünmek önemli değildir.

Bakın, Alan Kay akıllı biriydi / iyi bir fikri vardı, bu da bir dizi başka iyi fikre karşı çıktı ve bunun gerçekleştirilmesini Smalltalk ve diğer dillerde buldu.

O Mesih değildir ve OOP Tek Gerçek Programlama Paradigması değildir.

Birçoğu arasında iyi bir fikir. C ++, OOP zihniyetinden gelen iyi fikirlere sahip mi? Tabii ki öyle.


8

C ++ kapsülleme, kalıtım ve polimorfizm anlamına gelirse , OOP'yi destekler .

Ancak, C ++ gerçekten gelmez excel OOP de. Bunun bir nedeni, polimorfizmin genellikle (akıllı işaretçilerin kullanımına rağmen) çöp toplanmış bir dilde çalışmak için daha doğal olan yığın tahsisli nesnelere bağlı olmasıdır.

Ancak C ++ 'ın üstün olduğu yerde genel programlama vardır. C ++, şablon tabanlı fonksiyonel programlama teknikleriyle kolayca yüksek verimli, genel kod oluşturmanıza olanak tanır.


4

C ++, Simula'dan OOP özelliklerini ödünç aldı. Bir veya daha fazla Simula geliştiricisi IIRC, C ++ 'nın aklında olan şey olmadığını söyledi.

C ++ soyutlama için iyi araçlara sahiptir, ancak nesne yönelimli bir dilden daha karışık bir paradigma dilidir. Nesneye yönelik özellikler orada, ancak "katı OOP" olmayan seçenekleriniz var.

C ++ 'da elde ettiğiniz yaramaz "seçimlerden" biri, yöntemler için geç bağlama yerine erken kullanmaktır. Bu sadece mümkün değil, aynı zamanda varsayılan. Java'da "final" ilişkilidir, ancak bazı açılardan daha temizdir (yalnızca önemsiz bir performans yükünden kaçınmakla kalmayacak şekilde niyet belirtir) ve bu varsayılan değildir .

Bazı açılardan, C ++ hala burada olan erken bir deney olduğunun işaretlerini gösterir. Yine de, diğer OOP dillerinde alamadığınız birçok avantajı olan hala iyi bir araçtır.


2
C ++ OOP olmayanlara izin verir ve C ++ OOP'a izin verir, bazı dillerin OO olması için OOP'ye izin vermesi gerekir, bu nedenle C ++ bir OO dilidir.
Trinidad

1
Smalltalk şöhretinden Alan Kay, C ++ 'nın "nesne yönelimli" terimini yazarken aklında olan şey olmadığını söyledi. C ++, Simula sınıflarının C üzerine aşılanması ve hiçbir zaman temiz bir mola vermemesi "Sınıflarla C" olarak başladığından beri, erken bir deney gibi görünmesi şaşırtıcı değildir.
David Thornley

1
@Trinidad: HERHANGİ bir dil OOP'ye izin verir. Düz eski C oldukça güzel OO kodu gördüm. Evet, tüm sanal yöntem tablolarını elle tanımlamak acıdır, ancak dil açıkça izin verir .
Jan Hudec

4

Her şeyi bir sınıfın parçası olmaya zorlamak, mutlaka büyük OO kodu vermez.

Kötü bir prosedürel programcıdan Java'da programlamasını isteyin ve muhtemelen bir yere bir sınıf alacaklar, statik bir ana yöntem verecekler ve 1000 satır kod içereceklerdir. Gördüğümü biliyorum.

Java'nın bir anahtar deyimi vardır. Ben switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }vb C + + ve Java kodu gördüm .

C ++ birçok OO kavramını destekler, ancak standardı onun tarafından tanımlanmamıştır, ancak sanırım çok fazla hedefinizin ne olduğuna bağlıdır.

C ++ 'daki ana "zayıf" semantik, bir nesnenin başka bir nesneye geçtiği sınıfların kopya oluşturulmasına izin verir. Bunu devre dışı bırakabilirsiniz, ancak bir işlevden bir tane döndüremezsiniz. Neyse ki bu C ++ 0x ile ele alınmıştır.


3

OOP sadece her şeyin bir sınıfta olduğundan veya bir sınıfta olduğundan emin olmakla ilgili değildir. OO olmayan kodu "tamamen OO" dilinde yazmak mükemmel bir şekilde mümkündür. Örneğin, "ana" genellikle küresel bir işlev olarak belirtilir, ancak bir sınıfı yalnızca statik bir ana yöntem içerecek şekilde icat etmek, OO olmayan bir yöntemdir.

C ++ çeşitli şeylerin bir karışımı ile en iyi şekilde çalışır; bu şaşırtıcı olmamalı, çünkü en iyi şeyler en iyi şekilde işliyor. Çoğu zaman OOP bu çok kullanışlı araçlardan biridir.


2

C ++ OOP için kullanılabilir, ancak Smalltalk gibi bir şey kadar 'saf' değildir. C ++ ayrıca insanların konuştuğu şey olan OOP olmayan yapmanıza izin verir.


2

Duygulara katılmama rağmen, C ++ 'ın tip sisteminin saf OOP olmadığı - "her şey bir nesne" olmadığı doğrudur. Rakamlar (özellikle), Smalltalk'te olduğu gibi kolayca genişletilemez. Örneğin "2 + 2" nin anlamını yeniden tanımlayamazsınız ("iki + iki" nin anlamını yeniden tanımlayabilirsiniz).

Ancak çoğu insanın muhtemelen ne anlama geldiği, birçok insanın C ++ 'da nesne yönelimli olmayan kod yazmasıdır, ancak "OOP" dilini kullandıkları için nesne yönelimli olduklarına inanırlar. Bu doğru değil. Ama bence, Smalltalk'ta iğrenç zorunlu kod yazabilir ve C ++ 'da iyi bir OOP tasarımından daha üstün olamazsınız.


1

Alan Kay'ın C ++ 'a karşı mükemmel bir itirazı, C'nin üstünde bir makro dil olmasıydı.

"İleti iletme" kavramı, basitçe, sınıf örneklerinin hafızada tutulduğu ve çağrılabilecek yöntemleri ortaya koyduğu fikridir. İleti geçirme, C ++ 'ta işlevler için işaretçiler tutan * simüle edilir.

C ++ 'da mesaj geçişinin yanlış olduğunu söylemek, daha doğru söylenecek olan, mesaj geçişinin, diğer bir dilin ayrılmaz bir parçası olduğu ve dilin yabancı bir yapıyı önceden işlemediği ve doğrudan C üzerine aşılamadığı için smalltalk ve Java'yı seviyor olmasıdır.

Bu, sorgulayıcının deneyim seviyesinin biraz ötesinde olduğundan şüphelendiğim oldukça semantik bir dil tasarımı argümanıdır.

C ++ 'dan nefret etmek için binlerce neden ve onu sevmek için çok az neden olduğu söyleniyor.

Mükemmel çekiç ve mükemmel çiviyi aramak yerine, inşa etmek için mükemmel evi bulun ve sonra doğru araçları bulun ... deneyim gerektiren.

Alan Kay'ın korktuğu sistemlerin "saf OOP" olmadığını, aslında C ++ 'ın bir gücü olduğunu hatırlamak da önemlidir. Herkesinki kendine...


1
Amaç C ayrıca C'nin üstünde makro dili olarak başladı, ancak nesneye yönelik bir dildir.
Jan Hudec

1

Bana göre, bu bir kullanılabilirlik sorunu kadar tanımlayıcı bir konu değil.

Nesneler, karmaşık programları okumayı, yazmayı ve akıl yürütmeyi kolaylaştırmayı amaçlayan bir soyutlamadır. Pratik bir programcı için, bir dilin "nesne yönelimli" nin belirli bir biçimsel tanımının tüm kriterlerini karşılayıp karşılamadığı (birçok rakip olan var gibi görünmektedir!) Sunduğu araçların düşünmek için uygun olup olmadığı kadar önemli değildir. söz konusu nesneler açısından programınız, yani aslında OOP'un sözde verimlilik avantajlarından yararlanma.

C ++ 'da, nesneler , genellikle programcıları bu nesnelerin bellekte nasıl yapılandırıldığına dair kötü meselelerle - düz C'de kodlamayı diğer OOP dillerinden daha anımsatan konularla uğraşmaya zorlayan - çok sızdıran bir soyutlamadır. Örneğin, C ++ Sık Sorulan Yanıtlar bu eleştiriyi sunar (diğerleri arasında):

Bir uygulayıcının C ++ dışındaki OO sistemlerine ve C ++ 'nın "OO" olarak kabul edilmesine izin veren "kapsülleme, kalıtım, polimorfizm" üçlüsü dışındaki OO tanımlarına aşina olması çok faydalıdır. Örneğin, sınır denetimi veya çöp toplama işlemi olmayan bir ortamın bir OO ortamı olmadığı iddiası, C ++ 'a alışkın kişiler için çirkin geliyor. Ancak birçok açıdan bakıldığında, çok mantıklı. Herkes bir nesnenin üzerine yazabilirse, "kapsülleme" nerede? Bir nesneyi atmak sallanan referanslara veya bellek sızıntılarına yol açabilirse, sistem "nesne yönelimli" ? Belirli bir yerde ve zamanda ne tür bir nesnenin bulunduğunu söyleme yeteneğine ne dersiniz? Yazılımın nesnelerle çalıştığını söylüyorsunuz - neredeler? Ve eğer kimse bulamazsa, yazılımda nasıl hata ayıklanır?

C ++, nesne yönelimli, ancak hoş olmayan ve eksiktir: kullanıcıları, verilerinin hatalı bitlerden ziyade "gerçek" nesneler gibi davrandığından emin olmak için çok çaba harcamalıdır . Yani bunun çoğu, sınıflar ve dinamik sevk yararlanarak o 's besbelli bir şey bu yüzden, bir sürü kod süresi içinde C ++ ile yazılmış olan, söz konusu olabilir pratik OOP için kullanın.


Ciddi bir cevap olması gereken FQA referans için -1. FQA çarpıklıkların, yarı gerçeklerin ve yanlış anlamaların yuvasıdır.
David Thornley

@DavidThornley Özel teklif bir çarpıtma, yarı gerçek veya yanlış anlama mı?
Alex P

Orada bir yerlerde. Bir OO dilinin sınır denetimine (bazen C ++ standart kaplarına yerleştirilmiş) sahip olması ve çöp toplama (akıllı işaretçiler ilkel çöp toplamadır) iddiası zorunlu ve tutarsızdır. Sarkan referansların nesneye yönelik olmamasına izin veren bir dil hakkındaki cümle açık bir şekilde Blatant İddiası ile ispatlanmıştır. Ben "ne tür bir nesne söyleme yeteneği" şaşkın; işaretçi türü bunu sanal davranışı olmayan nesneler için verir ve RTTI bunu sanal davranışı olan nesneler için işler.
David Thornley

@DavidThornley FQA iddiası bir olmasıdır kullanışlı OO dil olmalıdır bu şeyler var - (? ++ "uygun" C olan) soru varlık sorulan ile uyumludur. Ben çıplak kemikler tanımları hakkında bir iddia gerçekten ele almaz ... "Söyleyebilme": bazı başlatılmamış veya daha önce üzerine yazılan verilere bir işaretçi takip ederek, gerçekten orada olmayan bir nesneye erişim ortak bir hata davranışı; ve programınız bu çöpü mutlu bir şekilde alıp veri olarak yorumlar ve ardından sınır dışı bir adrese ulaşana veya büyük bir hata oluşana kadar diğer çöp verilerine çöp işaretlerini takip eder.
Alex P

Ancak, alıntı en azından sınır kontrolü veya çöp toplama olmadan bir dilin OO olmadığı iddiasını şiddetle tavsiye etti ve isterseniz C ++ 'da bu şeylere sahip olduğunuz gerçeğini göz ardı etti. Bir dilin belirli hata sınıflarını önleyip önlemediği sorusu (herhangi bir nedenle) OO olup olmadığına diktir.
David Thornley

-1

Graham Lee'nin burada en çok oy almasının bir nedeni var. Tekrarlamak gerekirse, bir C ++ sınıfının gerçekten mesaj geçişi yapmadığı anlamında bir nesne olmadığı anlaşılmaktadır. Bence bu insanlar C ++ veya oop öğrenirken çok şey yukarı gezileri olduğunu. İnsanlara nesneye yönelik 'bu' olduğu söylenir ve daha sonra C ++ 'nın farklı şekilde yaptığı söylenir. C ++ hiçbir zaman farklı OOP yapmadı. Eğer bu şekilde düşünürseniz, C ++ sınıflarının ne anlama geldiğini asla takdir edemezsiniz ve bu, soyutlama ve dinamik davranışları birleştirerek yalnızca prosedürel paradigmada bir gelişme olduğu anlamına gelir. C ++ sınıfları temel olarak prosedüreldir, sadece prosedürel paradigmayı geliştirirler, ya da daha ziyade bir C yapısının daha gelişmiş bir versiyonudur.


Argümanlarınız için gerçek destekleyici nedenleriniz var mı? Görünüşe göre iddialarda bulunuyorsunuz ve aynı fikirde olmayanların yanılmaları gerektiğini ya da farklı bir şekilde bakarlarsa ya da belki de tam olarak OO tanımınızı paylaşmışlarsa zihinlerini değiştirmeleri gerektiğini iddia ediyorsunuz.
David Thornley

Yeterince adil. Bu makaleyi okuyabilirsiniz . Söylediğim şey, c ++ 'ın sıkı bir Alan Kay anlamda “nesne yönelimli programlama” olmadığıdır. Ancak, OOP'yi davranışı olan bir veri yapısı olarak tanımlarsanız, c ++ 'yı OOP olarak kabul edebilirsiniz. Zihnimde bir c ++ sınıfını daha yüksek bir yordamsal programlama soyutlaması olarak görmek daha doğru. Bir c ++ sınıfı, Kay stili bir nesneden çok daha etkilidir, ancak eşzamanlılık için daha kötüdür. Şahsen c ++ sınıfının harika bir tasarım olduğunu düşünüyorum.
annoying_squid

1
Bağlantı için teşekkürler, ancak sadece Alan Kay'ın ne anlama geldiğini açıklıyor. Dahası, Smalltalk'ın genellikle ilk OO dili olarak kabul edildiğine katılmıyorum ve Wikipedia, Stroustrup'un Sınıflar ile C oluşturmak için birleştirilen iki dilden biri olan Simula olduğunu kabul ediyor. Bir C ++ sınıfının bir nesne şablonundan daha üst düzey bir yordamsal programlama soyutlaması olduğu iddianızla ilgileniyorum, ama neden hala bu şekilde düşündüğünüzü anlamıyorum.
David Thornley

Eğer bu konuda hemfikir olabilirsek, Nesne Yönelimi muhtemelen öznel bir terimdir. Ancak bir Kay nesnesini, kodun ayrıştırılması ve eşzamanlı modülerliği tanıtmak için her nesnenin mesaj geçişi ile etkileşen mini bilgisayarlar gibi bir role hizmet etmesi anlamında daha doğal bir yol olarak görüyorum. Bu model altında 'b / c arasında çok az veya hiç kod olmaması gerekir'. Programın tüm mantığı hücre ve mesaj olarak ifade edilebilir. Karşılaştırma yapılırsa, 'sınıfların' kullanımı tipik olarak aralarında bazı prosedürel tutkal kodu gerektirir (gerçek modülerlikten yoksundur), ancak avantaj, sınıfların çok daha verimli olmasıdır.
annoying_squid

-1

Steve Yegge bunu en iyi şekilde söyledi :

C ++ dünyadaki en aptal dildir, gerçek anlamda en az duyarlı olmaktır. Kendini bilmiyor.

C ++ 'daki nesne sistemi , derleme zamanında o kadar kablolanmış ve sabittir ki, diğer şeylerin yanı sıra mesaj geçişi, içgözlem, yansıma, dinamik gönderme ve geç bağlama içeren orijinal OOP kavramından çok uzaktır. C ++ ve Smalltalk'ın ortak tek özelliği biraz kelime hazinesi.


Hangi yolla C ++ en az duyarlı dil? Bir dilin duyarlı olması ne anlama gelir? Yansıtma yeteneklerinden yoksun demekse, bu oldukça yaygındır ve kesinlikle C ++ bir kalabalığın arasından seçim yapmaz.
David Thornley

2
Dünyada "en iyi" dediğini nasıl söyleyebilirsin? Rastgele teklifin ne anlama geldiğine dair hiçbir fikrim yok.
user16764

+1, bu tür bir şeyin C ++ basher baser'larından çok fazla plak alacağını söyler, ancak söylenmesi gerekir - yansıma olmadan gerçekten OOP yapamazsınız, çünkü yatay malzemelere bakmak için jeneriklere sahip değilsiniz ( yönleri) - yaşam döngüsü (aktivasyon, bertaraf), genel hata işleme, genel proxy, genel serileştirme, genel görev paralelliği - bunlar kodunuzu kirletir ve SoC'yi keser.
vski

Teşekkürler. Yansımasız bir dilin OOP için iyi bir örnek olmadığını söylemek için -3'e ulaşmam gerektiğine inanamıyorum.
John Cromartie

1
@JohnCromartie, Cevabınızdaki bu noktayı ayrıntılandırabilir misiniz?
Jeremy Heiler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.