Bu çok önemli bir nokta, ama IMHO anlaşılmaya değer.
Tüm OO dilleri her zaman referansların kopyalarını oluşturur ve hiçbir zaman bir nesneyi 'görünmez' olarak kopyalamaz. OO dilleri başka bir şekilde çalıştıysa, program yazmak çok daha zor olurdu . Örneğin, işlevler ve yöntemler hiçbir zaman bir nesneyi güncelleyemez. Java ve çoğu OO dilinin, önemli bir karmaşıklık olmadan kullanımı neredeyse imkansız olacaktır.
Programdaki bir nesnenin bir anlamı olması gerekir. Örneğin, gerçek fiziksel dünyada belirli bir şeyi temsil eder. Aynı şeye birçok referans olması genellikle mantıklıdır. Örneğin, ev adresim birçok kişiye ve kuruluşa verilebilir ve bu adres her zaman aynı fiziksel yeri ifade eder. İlk nokta, nesneler genellikle spesifik, gerçek veya somut bir şeyi temsil eder; ve böylece aynı şeyle ilgili birçok referansa sahip olabilmek son derece yararlıdır. Aksi takdirde program yazmak daha zor olurdu.
Geçmek her zaman a
başka bir işlev, örneğin çağrı için bir bağımsız değişken / parametre olarak
foo(Dog aDoggy);
veya bir yöntem uygulanır a
, altta yatan program kodu aynı nesneye ikinci referans üretmek üzere, referans bir kopyasını çıkarır.
Ayrıca, kopyalanmış bir referansa sahip kod farklı bir iş parçacığındaysa, her ikisi de aynı nesneye erişmek için aynı anda kullanılabilir.
Bu nedenle, çoğu yararlı programda, aynı nesneye birden fazla referans olacaktır, çünkü çoğu OO programlama dilinin semantiği budur.
Şimdi, bunu düşünürsek, referansla geçmek birçok OO dilinde mevcut tek mekanizma olduğundan (C ++ her ikisini de destekler), 'doğru' varsayılan davranış olmasını bekleyebiliriz .
IMHO, referansları kullanmak için birkaç nedenden dolayı doğru varsayılan değerdir:
- İki farklı yerde kullanılan bir nesnenin değerinin aynı olduğunu garanti eder. Bir nesneyi iki farklı veri yapısına (diziler, listeler vb.) Yerleştirdiğinizi ve onu değiştiren bir nesne üzerinde bazı işlemler yaptığınızı düşünün. Hata ayıklamak için bir kabus olabilir. Daha da önemlisi, bu ise , her iki veri yapıları aynı nesne veya program bir hata vardır.
- Kodu birkaç işleve mutlu bir şekilde yeniden düzenleyebilir veya kodu birkaç işlevden biriyle birleştirebilirsiniz ve anlambilim değişmez. Dil referans anlambilimi sağlamıyorsa, kodu değiştirmek daha da karmaşık olacaktır.
Ayrıca bir verimlilik argümanı vardır; tüm nesnelerin kopyalarını oluşturmak bir referans kopyalamaktan daha az verimlidir. Ancak, bu noktayı kaçırdığını düşünüyorum. Aynı nesneye yapılan birden fazla referans daha mantıklıdır ve kullanımı daha kolaydır, çünkü gerçek fiziksel dünyanın anlambilimiyle eşleşirler.
Yani, IMHO, genellikle aynı nesneye birden fazla referans olması mantıklıdır. Bunun bir algoritma bağlamında mantıklı olmadığı olağandışı durumlarda, çoğu dil bir 'klon' veya derin kopya yapma yeteneği sağlar. Ancak bu varsayılan değildir.
Bunun varsayılan olmaması gerektiğini iddia eden insanlar , otomatik çöp toplama sağlamayan bir dil kullanıyorlar. Örneğin, eski moda C ++. Sorun şu ki, hala gerekli olabilecek nesneleri geri istememek için 'ölü' nesneleri toplamak için bir yol bulmaları gerekiyor; aynı nesneye birden fazla referans olması bunu zorlaştırır.
Bence, C ++ yeterince düşük maliyetli çöp toplama sahip olsaydı, tüm başvurulan nesneler çöp toplanır, o zaman itirazın çoğu gider. Referans semantiğin gerekli olmadığı bazı durumlar hala olacaktır . Ancak, tecrübelerime göre, bu durumları tanımlayabilen insanlar, genellikle uygun semantiği yine de seçebilirler.
Bir C ++ programında kod büyük miktarda çöp toplama veya hafifletmek için orada olduğuna dair bazı kanıtlar olduğuna inanıyorum. Ancak, bu tür bir 'altyapı' kodunun yazılması ve sürdürülmesi maliyet ekler; dili daha kolay veya daha sağlam hale getirmek için vardır. Bu nedenle, örneğin Go dili, C ++ 'nın bazı zayıflıklarını düzeltmeye odaklanarak tasarlanmıştır ve çöp toplama dışında bir seçeneği yoktur.
Bu elbette Java bağlamında önemsizdir. Kullanımı kolay olacak şekilde tasarlandı ve çöp toplama da yapıldı. Bu nedenle, birden çok referansa sahip olmak varsayılan semantiktir ve bunlara bir referans varken nesnelerin geri kazanılmaması açısından nispeten güvenlidir. Tabii ki bir veri yapısı tarafından tutulabilirler, çünkü program bir nesne ile gerçekten bittiğinde düzgün bir şekilde toplanmaz.
Öyleyse, sorunuza geri dönerek (biraz genelleme ile), ne zaman aynı nesneye birden fazla referans istersiniz? Aklıma gelen her durumda hemen hemen. Çoğu dil parametre geçiş mekanizmasının varsayılan semantikleridir. Bunun nedeni, gerçek dünyada var olan nesnelerin işlenmesinin varsayılan semantiğinin referans olarak olması gerektiğidir (çünkü gerçek nesneler oradadır).
Diğer herhangi bir anlambilimin ele alınması daha zor olurdu.
Dog a = new Dog("rover"); // initialise with name
DogList dl = new DogList()
dl.add(a)
...
a.setOwner("Mr Been")
Ben "rover" dl
tarafından etkilenen setOwner
veya programlar yazmak, anlamak, hata ayıklama veya değiştirmek zor olsun gerektiğini öneririz . Bence çoğu programcı şaşkın veya dehşete düşer.
daha sonra köpek satılır:
soldDog = dl.lookupOwner("rover", "Mr Been")
soldDog.setOwner("Mr Mcgoo")
Bu tür bir işlem yaygın ve normaldir. Bu nedenle referans anlambilimi varsayılan değerdir, çünkü genellikle en mantıklıdır.
Özet: Aynı nesneye birden fazla referans olması her zaman mantıklıdır.