C ++ 'ın neden yansıması yok?


337

Bu biraz tuhaf bir soru. Hedeflerim, dil tasarımı kararını anlamak ve C ++ 'da düşünme olanaklarını tanımlamaktır.

  1. C ++ dil komitesi neden dilde yansıma uygulamaya gitmedi? Sanal makinede çalışmayan bir dilde (java gibi) yansıma çok zor mu?

  2. Eğer biri C ++ için yansıma uygulayacak olsaydı, zorluklar neler olacak?

Sanırım yansıma kullanımları iyi bilinir: editörler daha kolay yazılabilir, program kodu daha küçük olur, birim testleri için alaylar oluşturulabilir vb. Ancak, yansıma kullanımları hakkında da yorum yapabilmeniz harika olurdu.

Yanıtlar:


631

C ++ 'da yansımayla ilgili çeşitli sorunlar vardır.

  • Eklenmesi gereken çok iş var ve C ++ komitesi oldukça muhafazakârdır ve ödeyeceğinden emin olmadıkça radikal yeni özelliklere zaman harcamayın. (.NET derlemelerine benzer bir modül sistemi eklemek için bir öneri yapıldı ve bence güzel olması konusunda genel bir fikir birliği olsa da, şu anda en büyük önceliği değil ve daha sonraya kadar geri itildi C ++ 0x.Bu özellik için motivasyon, #includesistemden kurtulmaktır , ancak en azından bazı meta verileri de etkinleştirir).

  • Kullanmadığın şeyin bedelini ödemiyorsun. Bu, C ++ 'ın altında yatan temel tasarım felsefelerinden biridir. Asla ihtiyacım olmasa neden kodum meta veriyi taşımalı? Ayrıca, meta verilerin eklenmesi, derleyicinin optimizasyonunu engelleyebilir. Bu meta verilere asla ihtiyacım olmasa neden kodumda bu maliyeti ödemeliyim?

  • Bu bizi başka bir büyük noktaya götürür: C ++ derlenmiş kod hakkında çok az garanti verir. Ortaya çıkan işlevsellik beklenen şey olduğu sürece, derleyicinin beğendiği her şeyi yapmasına izin verilir. Örneğin, sınıflarınızın aslında orada olması gerekmez . Derleyici bunları optimize edebilir, yaptıkları her şeyi satır içi yapabilir ve çoğu zaman bunu yapar, çünkü basit şablon kodu bile birkaç şablon örneği oluşturma eğilimindedir. C ++ standart kütüphanesi bu agresif optimizasyona dayanır . Functor'lar, yalnızca nesneyi örnekleme ve tahrip etme yükü optimize edilebilirse performans gösterir. operator[]bir vektörde yalnızca performanstaki ham dizi indeksleme ile karşılaştırılabilir, çünkü tüm operatör satır içine alınabilir ve böylece derlenmiş koddan tamamen kaldırılabilir. C # ve Java, derleyicinin çıktıları hakkında birçok garanti verir. C # 'da bir sınıf tanımlarsam , sonuçta oluşan derlemede bu sınıf bulunur . Hiç kullanmasam bile. Üye işlevlerine yapılan tüm çağrılar satır içine alınabilse bile. Sınıf orada olmalı, böylece yansıma onu bulabilir. Bunun bir kısmı, baytkoduna hangi aracı derleme C # hafiflediği JIT derleyicisi kutuİlk C # derleyicisi yapamasa bile, sınıf tanımlarını ve satır içi işlevleri seviyorsa kaldırın. C ++ 'da, yalnızca bir derleyiciniz vardır ve verimli kod çıkışı gerekir. Bir C ++ yürütülebilir dosyasının meta verilerini denetlemenize izin verildiyse, tanımladığı her sınıfı görmeyi beklersiniz, yani derleyici gerekli olmasa bile tüm tanımlanan sınıfları korumak zorunda kalacaktır.

  • Ve sonra şablonlar var. C ++ 'daki şablonlar diğer dillerdeki jeneriklere benzemez. Her şablon örneği yeni bir tür oluşturur . std::vector<int>sınıfından tamamen ayrı bir sınıftır std::vector<float>. Bu, bir programın tamamında çok sayıda farklı tür ekler. Yansımamız ne görmeli? Şablon std::vector ? Ancak bu, çalışma zamanında hiçbir anlamı olmayan bir kaynak kodu yapısı olduğundan nasıl olabilir? Ayrı sınıfları görmek zorundaydı std::vector<int>ve std::vector<float>. Ve std::vector<int>::iteratorve std::vector<float>::iteratoraynı içinconst_iteratorve bunun gibi. Ve şablon meta programlamasına adım attığınızda, hepsi derleyici tarafından satır içine alınan ve kaldırılan yüzlerce şablonu hızla sonuçlandırırsınız. Derleme zamanı metaprogramının bir parçası olarak hiçbir anlamı yoktur. Tüm bu yüzlerce sınıf düşünmeye açık olmalı mı? Yapmaları gerekecekti, çünkü aksi takdirde bizim tanımladığımız sınıfların gerçekten orada olacağını garanti etmezse, yansımamız işe yaramaz olurdu . Ve bir yan sorun, şablon sınıfının örnekleninceye kadar var olmamasıdır. Kullanan bir program düşünün std::vector<int>. Yansıma sistemimiz görebilmeli std::vector<int>::iteratormi? Bir yandan, kesinlikle beklersiniz. Bu önemli bir sınıfı, ve o açısından tanımlanır oluyor std::vector<int>ki, yaparmeta verilerde mevcut. Öte yandan, program bu yineleyici sınıf şablonunu hiçbir zaman gerçekten kullanmazsa , türü hiçbir zaman başlatılmaz ve bu nedenle derleyici sınıfı ilk sırada oluşturmaz. Ve kaynak koduna erişim gerektirdiğinden çalışma zamanında oluşturmak için çok geç.

  • Ve son olarak, yansıma C ++ 'da olduğu gibi C ++ kadar hayati değildir. Nedeni yine şablon meta programlamasıdır. Her şeyi çözemez, ancak aksini düşünmeye başvurduğunuz birçok durumda, derleme zamanında aynı şeyi yapan bir metaprogram yazmak mümkündür. boost::type_traitsbasit bir örnektir. Tip hakkında bilmek ister misiniz T? Kontrol edin type_traits. C # 'da, yansımasını kullanarak türünden sonra balık tutmanız gerekir. Yansıma bazı şeyler için hala yararlı olacaktır (meta programlamanın kolayca değiştiremediği ana kullanım, otomatik oluşturulmuş serileştirme kodu içindir), ancak C ++ için bazı önemli maliyetler taşıyacaktır ve bu kadar sık ​​gerekli değildir diğer dillerde.

Düzenleme: Yorumlara yanıt olarak:

cdleary: Evet, hata ayıklama sembolleri, yürütülebilir dosyada kullanılan türlerle ilgili meta verileri depoladıkları için benzer bir şey yapar. Ama aynı zamanda tarif ettiğim problemlerden de muzdaripler. Bir sürüm derlemesinde hata ayıklamayı denediyseniz ne demek istediğimi anlayacaksınız. Kaynak kodda, son kodda satır içine alınmış bir sınıf oluşturduğunuz büyük mantıksal boşluklar vardır. Yansımayı yararlı bir şey için kullanacak olsaydınız, daha güvenilir ve tutarlı olması gerekirdi. Olduğu gibi, türler neredeyse her derlediğinizde kaybolur ve yok olur. Küçük bir ayrıntıyı değiştirirsiniz ve derleyici, hangi türlerin satır içine alınacağını ve hangilerinin yanıt vermeyeceğini değiştirmeye karar verir. Bundan yararlı bir şeyi nasıl elde edersiniz? en alakalı türlerin meta verilerinizde temsil edileceği garanti edilmiyor mu? Aradığınız tip son yapıda orada olabilirdi, ama şimdi gitti. Ve yarın, birisi küçük bir masum işlevinde küçük bir masum değişikliği kontrol edecek, bu da tipi tamamen eğimli olmayacak kadar büyük yapıyor, bu yüzden tekrar geri dönecek. Bu hata ayıklama sembolleri için hala yararlıdır, ancak bundan daha fazlası değildir. Bu şartlar altında bir sınıf için serileştirme kodu oluşturmaya çalışmaktan nefret ederdim. ama bundan daha fazlası değil. Bu şartlar altında bir sınıf için serileştirme kodu oluşturmaya çalışmaktan nefret ederdim. ama bundan daha fazlası değil. Bu şartlar altında bir sınıf için serileştirme kodu oluşturmaya çalışmaktan nefret ederdim.

Evan Teran: bu konular Tabii olabilir çözülecek. Ama bu benim 1. noktama geri dönüyor. Çok iş gerektiriyordu ve C ++ komitesinin daha önemli olduğunu düşündükleri birçok şey var. C ++ 'da sınırlı bir yansıma (ve sınırlı olacaktır) elde etmenin faydası, diğer özellikler pahasına buna odaklanmayı haklı çıkaracak kadar büyük mü? Zaten (çoğunlukla) QT'ler gibi kütüphaneler ve ön işlemciler aracılığıyla yapılabilecek temel dilin özelliklerinin eklenmesinde gerçekten büyük bir fayda var mı? Belki de ihtiyaç, bu tür kütüphanelerin varlığından çok daha az acil. Bununla birlikte, belirli önerileriniz için, şablonlara izin vermemek tamamen işe yaramaz hale getireceğine inanıyorum. Örneğin, standart kitaplıktaki yansımayı kullanamazsınız. Ne tür bir yansıma olmaz?std::vector? Şablonlar C ++ 'ın büyük bir parçasıdır. Şablonlarda çalışmayan bir özellik temel olarak işe yaramaz.

Ama haklısın, bir tür yansıma uygulanabilir. Ancak dilde büyük bir değişiklik olurdu. Şu an olduğu gibi, türler sadece derleme zamanı bir yapıdır. Derleyicinin yararı için varlar ve başka hiçbir şey yok. Kod derlenmiş edildikten sonra, orada olan hiçbir sınıflar. Kendinizi esnetirseniz, işlevlerin hala var olduğunu iddia edebilirsiniz, ancak gerçekten, bir sürü atlama montajcı talimatı ve bir sürü yığın itme / pop'su var. Böyle bir meta veri eklerken devam edecek çok şey yok.

Ancak dediğim gibi, derleme modelinde değişiklikler, bağımsız modüller ekleme, belirli türler için meta veriler depolama, diğer modüllerin #includes ile uğraşmak zorunda kalmadan bunları referans almalarına izin vermek için bir teklif var . Bu iyi bir başlangıç ​​ve dürüst olmak gerekirse, standart komitenin teklifi çok büyük bir değişiklik olduğu için atmadığına şaşırdım. Belki 5-10 yıl içinde? :)


2
Bu sorunların çoğunun zaten hata ayıklama simgeleriyle çözülmesi gerekmez mi? Performanslı olacağından değil (bahsettiğiniz satır içi ve optimizasyon nedeniyle), ancak hata ayıklama sembollerinin yaptığı her şeyi yaparak yansıma olasılığına izin verebilirsiniz .
cdleary

2
İlk noktanız hakkında başka bir şey: bildiğim kadarıyla kimse bir C ++ uygulamasına yansıma eklemeyi denemedi. Bununla ilgili iyi bir deneyim yok. Komite muhtemelen başta exportve sonrasında olmak üzere liderlik yapmak konusunda isteksiz davranacaktır vector<bool>.
David Thornley

18
C ++ çalışma zamanı yansıması olmamalıdır katılıyorum. Ancak derleme zamanı yansıması yukarıdaki sorunlardan birkaçıdır ve birinin istediği takdirde belirli sınıflar üzerinde çalışma zamanı yansıması oluşturması için kullanılabilir. Bir sınıfın n. Yönteminin ve n. Üst öğesinin türüne, adına ve özelliklerine şablon aracılığıyla erişebiliyor musunuz? Ve derleme zamanında böyle sayısı olsun? Kimse kullanmadığı şey için ödeme yapmazken, CRTP tabanlı otomatik yansıma yapılabilir.
Yakk - Adam Nevraumont

15
Üçüncü noktanız birçok açıdan en önemlisidir: C ++, belleğin paraya mal olduğu platformlarda bağımsız kod yazmak için uygundur; kullanılmayan bir kodun kaldırılması, bir programın 2,50 ABD doları olan bir maliyet yerine 2,00 ABD doları olan bir mikro denetleyiciye sığmasına izin verirse ve kod 1.000.000 birimde gidiyorsa, bu kodun ortadan kaldırılması 500.000 ABD doları tasarruf sağlayabilir. Yansıma olmadan, statik analiz genellikle ulaşılamayan kodun% 90'ını + belirleyebilir; Yansıtmaya izin veriliyorsa, Yansıtma yoluyla ulaşılabilecek her şeye,% 90'ı olmasa bile ulaşılabilir olduğu varsayılacaktır.
Supercat

2
Kurulunda ile kolayca geliştirilebilir bir şey kesinlikle yoktur, sonunda beyaz üzerine siyah demek ki typeinfo'nın name()fonksiyonu tanımsız programcı değil bir şey tarafından yazdığınız adını döndürür GEREKİR. Bize sayıcılar için de bir ipucu verin. Bu yapımında yardımcı seri / seri kaldırma için gerçekten çok önemlidir fabrikalar vb
v.oddou

38

Yansıma, sorgulanabilecek bir yerde saklanabilecek türlerle ilgili bazı meta veriler gerektirir. C ++ yerel makine kodunu derlediğinden ve optimizasyon nedeniyle ağır değişikliklere maruz kaldığından, uygulamanın yüksek düzeyde görünümü derleme sürecinde hemen hemen kaybolur, sonuç olarak bunları çalışma zamanında sorgulamak mümkün olmayacaktır. Java ve .NET, sanal makineler için ikili kodda çok yüksek düzeyde bir gösterim kullanır ve bu yansıtma düzeyini mümkün kılar. Bununla birlikte, bazı C ++ uygulamalarında, Çalışma Zamanı Türü Bilgisi (RTTI) adı verilen ve yansımanın soyulmuş bir versiyonu olarak düşünülebilecek bir şey vardır.


15
RTTI, C ++ standardındadır.
Daniel Earwicker

1
Ancak tüm C ++ uygulamaları standart değildir. RTTI'yı desteklemeyen uygulamalar gördüm.
Mehrdad Afshari

3
RTTI'yi destekleyen uygulamaların çoğu, derleyici seçenekleri aracılığıyla kapatılmasını da destekler.
Michael Kohne

21

Tüm diller, diğer her dilin özelliklerini içermemelidir.

C ++ aslında çok, çok karmaşık bir makro birleştiricisidir. C #, Java, Objective-C, Smalltalk, vb.Gibi üst düzey bir dil DEĞİL (geleneksel anlamda).

Farklı işler için farklı araçlara sahip olmak iyidir. Sadece çekiçlerimiz varsa, her şey çivi gibi görünecektir. Betik dillerine sahip olmak bazı işler için yararlıdır ve yansıtıcı OO dilleri (Java, Obj-C, C #) başka bir iş sınıfı için yararlıdır ve süper Verimli çıplak kemikler makineye yakın diller başka bir iş sınıfı için de yararlıdır (C ++, C, Assembler).

C ++, Assembler teknolojisini inanılmaz karmaşıklık yönetimi düzeylerine genişletmenin inanılmaz bir işini yapar ve programlamayı daha büyük, daha karmaşık görevleri insanlar için çok daha mümkün kılmak için soyutlamalar yapar. Ancak, sorunlarına kesinlikle üst düzey bir perspektiften (Lisp, Smalltalk, Java, C #) yaklaşanlar için en uygun dil olması gerekmez. Sorunlarınıza en iyi çözümü uygulamak için bu özelliklere sahip bir dile ihtiyacınız varsa, hepimizin kullanması için bu dilleri yaratanlara teşekkür edin!

Ancak C ++, hangi nedenle olursa olsun, kodları ve altta yatan makinenin çalışması arasında güçlü bir korelasyona ihtiyaç duyanlar içindir. İster verimliliği, ister aygıt sürücülerini programlama, ister alt düzey işletim sistemi hizmetleriyle etkileşim ya da her neyse, C ++ bu görevler için daha uygundur.

C #, Java, Objective-C, bunların yürütülmesini desteklemek için çok daha büyük, daha zengin bir çalışma zamanı sistemi gerektirir. Söz konusu çalışma zamanının söz konusu sisteme teslim edilmesi gerekir - yazılımınızın çalışmasını desteklemek için önceden yüklenmiş. Ve bu katman, bazı platform sistemleri için korunmalı ve bazı platformlar üzerinde çalışması için BAZI DİĞER DİL tarafından özelleştirilmelidir. Ve bu orta katman - ana işletim sistemi ile kodunuz arasındaki bu uyarlanabilir katman - çalışma zamanı, neredeyse her zaman C veya C ++ gibi bir dilde yazılır, burada verimlilik # 1'dir, burada yazılım ve donanım arasındaki tam etkileşimin iyi anlaşılabileceği anlaşıldı ve maksimum kazanca dönüştürüldü.

Smalltalk, Objective-C seviyorum ve yansıma, meta veri, çöp toplama, vb ile zengin bir çalışma zamanı sistemine sahip. İnanılmaz kod bu tesislerden yararlanmak için yazılabilir! Ancak bu, yığın üzerinde daha yüksek bir katman, en sonunda OS ve donanımın üzerine oturması gereken alt katmanlara dayanması gereken bir katman. Ve bu katmanı oluşturmak için her zaman en uygun dile ihtiyacımız olacaktır: C ++ / C / Assembler.

Zeyilname: C ++ 11/14, C ++ üst düzey soyutlamaları ve sistemleri desteklemek için yeteneğini genişletmeye devam etmektedir. İş parçacığı oluşturma, senkronizasyon, hassas bellek modelleri, daha hassas soyut makine tanımları, C ++ geliştiricilerinin, bu üst düzey yalnızca bazı dillerin özel alanlara sahip olduğu yüksek düzey soyutlamaların çoğunu elde etmelerini sağlarken, metal performansı ve mükemmel öngörülebilirlik (yani minimum çalışma zamanı alt sistemleri). Belki de yansıma olanakları, C ++ 'ın gelecekteki bir revizyonunda seçici olarak etkinleştirilecektir, isteyenler için - veya belki de bir kütüphane bu tür çalışma zamanı hizmetleri sağlayacaktır (belki şimdi bir tane var mı, yoksa bir tane başlıyor mu?).


Başka bir dilde derlenmesi gereken bir dilin çalışma zamanı hakkındaki amacınız, Objective-C durumunda doğru değildir, çünkü çalışma zamanı C dilinde yazılmıştır (Objective-C'nin bir üst kümesidir).
Richard J. Ross III

Bu farksız bir ayrım. Sonunda Objective-C'nin kullandığı çalışma zamanı alt sistemi aslında Objective-C'de değil, C'de yazıldığında ne fark eder?
Mordachai

3
Üzgünüm; ancak düzgün bir şekilde bağladığınız sürece, C'de bir objektif-c programı derleyebilirsiniz, aslında burada yaptım: stackoverflow.com/a/10290255/427309 . Yukarıdaki ifadenizin tamamı yanlış. Çalışma zamanına C aracılığıyla tamamen erişilebilir ve onu bu kadar güçlü bir dinamik dil haline getiren şeylerden biridir.
Richard J. Ross III

1
"C çalışma zamanı" yalnızca C standart kitaplığının kodunu içeren dinamik bir kitaplıktır. "C ++ çalışma zamanı" için de aynı şey geçerli. Objective-C gibi bir çalışma zamanı sisteminden oldukça farklı. Ayrıca ... teknik olarak C'de Objective-C çalışma zamanını kullanabileceğinizi varsayarsak, bu hala sadece Objective-C çalışma zamanını kullanan bir C programı - C'de gerçek bir Objective-C programı
derleyemezsiniz

2
C ++ 11 sahip olan bir bellek modeli + atomik yapar daha taşınabilir birleştiriciye gibi. Bunlar üst düzey şeyler değil , C ++ 'nın daha önce taşınabilir desteğe sahip olmadığı düşük seviye şeyler. Ancak yanlış bir şey yaparsanız C ++ 'daki UB miktarı, Java gibi VM tabanlı dillerden ve ayrıca belirli bir montaj dilinden farklı olarak bunu yapar. Örneğin, imzalı taşma C ++ kaynağında tamamen UB'dir ve derleyici x86 diyelim için derlemiş olsa bile bu gerçeğe göre optimizasyon yapabilir , ancak neredeyse tüm platformlarda asm içinde sarılır. Modern C ++ taşınabilir bir montaj dilinden çok uzaktır.
Peter Cordes

11

C ++ ile ilgili tasarım kararlarını gerçekten anlamak istiyorsanız, Ellis ve Stroustrup'un Annotated C ++ Referans Kılavuzunun bir kopyasını bulun . En son standartla güncel DEĞİLDİR, ancak orijinal standarttan geçer ve işlerin nasıl çalıştığını ve sıklıkla nasıl bu şekilde olduklarını açıklar.


6
Ayrıca Stroustrup tarafından C ++ Tasarım ve Evrimi
James Hopkin

9

Sahip olduğu diller için düşünme, derleyicinin yansıma sağlamak için kaynak kodunun ne kadarını nesne kodunuzda bırakmak istediği ve yansıyan bilgileri yorumlamak için ne kadar analiz makinesinin mevcut olduğu ile ilgilidir. Derleyici tüm kaynak kodunu etrafta tutmadıkça, yansıma kaynak koduyla ilgili mevcut gerçekleri analiz etme kabiliyetiyle sınırlı olacaktır.

Eğer yansıma alamadım bu yüzden C ++ derleyicisi, (RTTI görmezden iyi) etrafında bir şey tutmaz içinde dilin. (Java ve C # derleyicileri yalnızca sınıf, yöntem adları ve döndürme türlerini saklar, böylece biraz yansıma verisi elde edersiniz, ancak ifadeleri veya program yapısını denetleyemezsiniz ve bu, "yansıma etkin" dillerde bile elde edebileceğiniz bilgiler oldukça seyrek ve sonuç olarak çok fazla analiz yapamazsınız).

Ancak dilin dışına çıkıp tam yansıtma yetenekleri elde edebilirsiniz. C'deki yansımayla ilgili başka bir yığın taşması tartışmasının cevabı bunu tartışıyor.


7

Yansıma daha önce c ++ ile uygulanabilir ve uygulanmıştır.

Yerel bir c ++ özelliği değildir, çünkü dil tarafından varsayılan olarak ayarlanmaması gereken ağır bir maliyeti (bellek ve hız) vardır - dil "varsayılan olarak maksimum performans" yönündedir.

İhtiyacınız olmayan şey için ödeme yapmamanız gerektiğinden ve kendinizin söylediği gibi editörlerde diğer uygulamalardan daha fazla ihtiyaç duyulduğu için, yalnızca ihtiyacınız olan yere uygulanmalı ve tüm koda "zorla" getirilmemelidir ( bir editörde veya benzer bir uygulamada üzerinde çalışacağınız tüm verilerin yansımasına ihtiyacınız yoktur).


3
ve semboller göndermezsiniz çünkü müşterilerinizin / rakiplerinizin kodunuza bakmasına izin verir ... bu genellikle kötü bir şey olarak kabul edilir.
gbjbaanb

Haklısın, kod sergi sorunu hakkında bile düşünmedim :)
Klaim

6

C ++ 'ın yansıması olmamasının nedeni, derleyicilerin, bir sınıf türünün üyeleri, üyeler hakkında, işlevler ve her şey hakkında bilgi gibi nesne dosyalarına sembol bilgileri eklemesini gerektirmesidir. Bu temelde, bildirimlerle gönderilen bilgiler daha sonra bu nesne dosyalarından (daha sonra modüller) okunacağından, içerme dosyalarını işe yaramaz hale getirir. C ++ 'da, bir tür tanımı, ilgili başlıkları ekleyerek (tüm bu tanımların aynı olması şartıyla) bir programda birden çok kez oluşabilir; burada komplikasyon. Düzinelerce sınıf şablonu örneğini optimize edebilen bir C ++ derleyicisi tarafından yapılan agresif optimizasyon, bir başka güçlü noktadır. Mümkün, ancak C ++ C ile uyumlu olduğu için,


1
Derleyicinin agresif optimizasyonunun nasıl güçlü bir nokta olduğunu anlamıyorum. Detaylandırabilir misin? Bağlayıcı yinelenen satır içi işlev tanımlarını kaldırabilirse, yinelenen yansıma bilgileriyle ilgili sorun nedir? Hata ayıklayıcılar için nesne bilgilerine sembol bilgisi yine de eklenmiyor mu?
Rob Kennedy

1
Sorun, yansıma bilgilerinizin geçersiz olması olabilir. Derleyici sınıf tanımlarınızın% 80'ini ortadan kaldırırsa, yansıtma meta verileriniz ne söyler? C # ve Java'da dil, bir sınıf tanımlarsanız tanımlanmış olarak kalmasını garanti eder. C ++ derleyicinin onu optimize etmesini sağlar.
jalf

1
@Rob, optimizasyonlar çoklu sınıf komplikasyonuna bağlı olmayan başka bir noktadır. Ne demek istediğimi görmek için @ jalf'in yorumuna (ve cevabına) bakın.
Johannes Schaub - litb

4
<T> 'yi yansıtırsam, T'nin bilgilerini atmayın. Bu çözülemez bir sorun gibi görünmüyor.
Joseph Garvin

3

C ++ 'da, şablon meta-programlama gibi derleme zamanı yapıları kullanılarak yeterince ele alınamayan yansımayı kullanmak için tonlarca vaka vardır.

N3340 , C ++ 'da yansımayı tanıtmanın bir yolu olarak zengin işaretçiler önerir. Diğer şeylerin yanı sıra, bir özelliği kullanmadığınız sürece ödeme yapmama sorununu da giderir.


2

Alistair Cockburn'e göre, yansıtıcı bir ortamda alt tipleme garanti edilemez .

Yansıma, gizli yazma sistemleriyle daha ilgilidir. C ++ 'da, hangi türe sahip olduğunuzu ve onunla ne yapabileceğinizi biliyorsunuz.


Daha genel olarak, Tanımsız Davranış getirmeden var olmayan bir özelliğin varlığını kontrol etme yeteneği, bu özelliğin bir sınıfın sonraki bir sürümüne eklenmesinin önceden var olan programların iyi tanımlanmış davranışını değiştirmesini ve sonuç olarak, bu özelliğin eklenmesinin bir şeyi "bozmayacağını" garanti etmeyi imkansız hale getirin.
Supercat

2

Yansıma, bir önişlemci yönergesi gibi isteğe bağlı olabilir. Gibi bir şey

#pragma enable reflection

Bu şekilde her iki dünyanın da en iyisini elde edebiliriz, bu pragma kütüphaneleri yansıtılmadan (tartışıldığı gibi herhangi bir ek yük olmadan) oluşturulacak, o zaman hız veya kullanım kolaylığı isteseler bireysel geliştirici olacaktır.


2

C ++ aşağıdakilere sahip olabilirse:

  • değişken adları, değişken türleri ve constdeğiştirici için sınıf üyesi verileri
  • işlev bağımsız değişkenleri yineleyicisi (yalnızca ad yerine konum)
  • işlev adları, dönüş türü ve constdeğiştirici için sınıf üyesi verileri
  • Üst sınıfların listesi (tanımlandığı sırayla)
  • şablon üyeleri ve üst sınıflar için veriler; genişletilmiş şablon (gerçek türün anlamı, 'oraya nasıl ulaşılacağına ilişkin şablon bilgileri' için değil, yansıma API'sı için kullanılabilir olacaktır)

Bu, günümüzün web ve veritabanı uygulamalarında (tüm orklar, mesajlaşma mekanizmaları, xml / json ayrıştırıcılar, veri serileştirme, vb.)

Örneğin, http://qt.nokia.com/doc/4.5/properties.htmlQ_PROPERTY makrosunun desteklediği temel bilgiler sınıf yöntemlerini ve e) kapsayacak şekilde genişletildi - C ++ ve genel olarak yazılım topluluğu.

Kesinlikle bahsettiğim yansıma anlamsal anlamı veya daha karmaşık sorunları (yorumlar kaynak kodu satır numaraları, veri akışı analizi vb. Gibi) kapsamaz - ama bunların bir dil standardının bir parçası olması gerektiğini de düşünmüyorum.


@Vlad: Evet, biri dile yansımayı destekleyen özellikler eklerse, dilde yansıtma elde edersiniz. Bu sadece dil komitesi karar verirse gerçekleşir ve sanırım 2011 itibariyle değiller ve MS 2020'den önce başka bir C ++ standardı olacağından şüpheliyim. Güzel düşünce. Bu arada, ilerleme kaydetmek istiyorsanız, büyük olasılıkla C ++ dışına çıkmanız gerekecektir.
Ira Baxter


0

C ++ yansıması, C ++ veritabanı erişimi, Web oturumu işleme / http ve GUI geliştirme için bir dil olarak kullanılacaksa çok önemli olduğuna inanıyorum. Yansıtma eksikliği ORM'leri (Hazırda Bekletme veya LINQ gibi), sınıfları, Veri serileştirmeyi ve diğer birçok konuyu başlatan XML ve JSON ayrıştırıcılarını (başlangıçta türsüz verilerin bir sınıf örneği oluşturmak için kullanılması gerektiği durumlarda) önler.

Oluşturma işlemi sırasında bir yazılım geliştiricisinin kullanabileceği bir derleme zamanı anahtarı, bu 'kullandığınız kadar ödersiniz' endişesini ortadan kaldırmak için kullanılabilir.

Ben bir firmwaredeveloper bir seri port veri okumak için yansıması gerekmez - o zaman iyi anahtarı kullanmayın. Ancak C ++ kullanmaya devam etmek isteyen bir veritabanı geliştiricisi olarak, veri üyeleri ve veritabanı yapıları arasındaki Verileri eşleyen korkunç, bakımı zor bir kodla sürekli olarak aşamalıyorum.

Ne serileştirme ne de diğer mekanizma yansımayı gerçekten çözmüyor - derleyici tarafından yapılmalıdır - ve bir kez yapıldıktan sonra C ++ okullarda tekrar düşünülecek ve veri işleme ile ilgili yazılımlarda kullanılacaktır.

Bana göre bu sayı # (ve saf diş açma ilkelleri sayı # 2'dir).


4
Kim C ++ söyledi olan bir DB Erişim için dil, Web oturumu hnadling veya gui dev olarak kullanılmak üzere? Bu tür şeyler için kullanılacak çok daha iyi diller var. Ve derleme zamanı anahtarı sorunu çözmez. Genellikle, yansımayı etkinleştirme veya devre dışı bırakma kararı dosya başına esas alınmaz. Bireysel tiplerde etkinleştirilebiliyorsa işe yarayabilir. Programcı, bir tür tanımlarken bir öznitelik veya benzeri ile belirtebiliyorsa, bunun için yansıma meta verilerinin oluşturulup oluşturulmayacağı. Ama küresel bir değişim? Sadece% 10'unu daha basit hale getirmek için dilin% 90'ını saklıyor olacaksınız.
jalf

Sonra, çapraz platform ve bir GUI erişimi olan bir program istiyorum, ne kullanmalıyım? Esnek olmayan java salıncak? Windows sadece C #? Ancak gerçek söylenmelidir ve gerçek şu ki, yürütülebilir kodda derlenen ve gui arayüzü ve veritabanlarına erişim sunan birçok program vardır, bu yüzden bazı veritabanı ve gui desteği kullanmalıdırlar ... t QT kullanarak. (MT (canavar araç kiti) olarak adlandırılmış olmalıdır)
Coyote21 20

1
@ Coyote21: C # yıllardır yalnızca Windows olmamıştır. (Mono'nun hayranı olmasam da, çoğu şey için yeterince iyi çalışıyor.) Ve Swing, Java için tek GUI araç takımı değil. Gerçek şu ki, çapraz platform istiyorsanız her ikisi de daha iyi bir seçim olacaktır. Eğer önemsiz olmayan bir şey yapıyorsanız, C ++ hemen hemen her zaman burada veya orada platforma özgü parçalara sahip olacaktır.
cHao

ORM için düşünmeye ihtiyaç duymanız için hiçbir neden yoktur. Tüm bunları şablonlarla gerçekleştirebilirsiniz. C ++ için ORM sağlayan çerçeve alanı vardır.
MrFox

0

Temelde bir "isteğe bağlı ekstra" olduğu için. Birçok kişi, Java ve C # gibi diller üzerinde C ++ 'ı seçer, böylece derleyici çıktısı üzerinde daha fazla kontrole sahip olurlar, örneğin daha küçük ve / veya daha hızlı bir program.

Yansıma eklemeyi seçerseniz, çeşitli çözümler mevcuttur .

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.