Bir tutamacın bir tür işaretçi olduğu, ancak öyle olmadığı ve nesnenin kendisinden ziyade bir nesneye referans tutmanıza izin verdiği söylendi. Daha ayrıntılı bir açıklama nedir?
Bir tutamacın bir tür işaretçi olduğu, ancak öyle olmadığı ve nesnenin kendisinden ziyade bir nesneye referans tutmanıza izin verdiği söylendi. Daha ayrıntılı bir açıklama nedir?
Yanıtlar:
Bir tutamaç, bir tamsayı indeksinden bir göstericiye, çekirdek uzayındaki bir kaynağa kadar her şey olabilir. Buradaki fikir, bir kaynağın soyutlamasını sağlamasıdır, bu nedenle onu kullanmak için kaynağın kendisi hakkında fazla bir şey bilmenize gerek yoktur.
Örneğin, Win32 API'deki HWND, bir Pencere için bir tanıtıcıdır. Kendi başına işe yaramaz: ondan herhangi bir bilgi toplayamazsınız. Ancak bunu doğru API işlevlerine aktarın ve bununla çok sayıda farklı numara gerçekleştirebilirsiniz. Dahili olarak, HWND'yi sadece GUI'nin pencere tablosuna bir dizin olarak düşünebilirsiniz (bu, nasıl uygulandığı olmayabilir, ancak sihrin mantıklı olmasını sağlar).
DÜZENLEME: Sorunuzda özellikle ne sorduğunuzdan% 100 emin değilim. Bu, esas olarak saf C / C ++ hakkında konuşuyor.
Tutamaç, kendisine görünür bir tür eklenmemiş bir işaretçi veya dizindir. Genellikle şöyle bir şey görürsünüz:
typedef void* HANDLE;
HANDLE myHandleToSomething = CreateSomething();
Yani kodunuzda sadece HANDLE'ı opak bir değer olarak geçirirsiniz.
Nesneyi kullanan kodda, işaretçiyi gerçek bir yapı tipine çevirir ve kullanır:
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
Ya da bir dizi / vektöre dizin olarak kullanır:
int doSomething(HANDLE s, int a, int b) {
int index = (int)s;
try {
Something& something = vecSomething[index];
return something.doit(a, b);
} catch (boundscheck& e) {
throw SomethingException(INVALID_HANDLE);
}
}
Bir tutamaç , tipik olarak bazı varlıkları referans göstermenin bir yolu olduğu için bir tür işaretçidir.
Bir işaretçinin bir tür tutamaç olduğunu söylemek daha doğru olur, ancak tüm tutamaçlar işaretçi değildir.
Örneğin, bir tutamaç, aynı zamanda, kendisi bir nesneye işaretçi içeren bir girdiye karşılık gelen bir bellek tablosuna bir dizin de olabilir.
Önemli olan, bir "tutamağa" sahip olduğunuzda, bu tutamacın aslında tanımladığı şeyi tanımlayacağını ne bilemezsiniz ne de umursamazsınız, bilmeniz gereken tek şey onun yaptığıdır.
Aynı sistemde bile farklı şeylere yönelik tutamaçlar "başlık altında" farklı şekillerde uygulanabileceğinden, "tam olarak bir tutamaç" ın tek bir cevabı olmadığı da açık olmalıdır. Ancak bu farklılıklarla ilgilenmenize gerek yok.
C ++ / CLI'de, bir tutamaç, GC yığınında bulunan bir nesneye bir göstericidir. (Yönetilmeyen) C ++ öbeği üzerinde bir nesnenin oluşturulması kullanılarak elde edilir new
ve bir new
ifadenin sonucu "normal" bir göstericidir. Yönetilen bir nesne, bir gcnew
ifade ile GC (yönetilen) yığınında tahsis edilir . Sonuç bir tutamaç olacaktır. Kollarda işaretçi aritmetiği yapamazsınız. Kolları serbest bırakmıyorsun. GC bunlarla ilgilenecek. Ayrıca, GC yönetilen yığın üzerindeki nesneleri yeniden konumlandırmakta ve program çalışırken yeni konumlara işaret etmek için tutamaçları güncellemek için serbesttir.
Bu , aynı zamanda Pimpl deyimi olarak da adlandırılan Handle-Body-Idiom bağlamında ortaya çıkar . Bir kütüphanenin ABI'sini (ikili arabirim), gerçek verileri başka bir sınıf nesnesinde tutarak aynı tutmaya izin verir, bu yalnızca bir "tutamaç" nesnesinde tutulan bir işaretçi tarafından referans alınır, bu sınıfa delege eden işlevlerden oluşur " Vücut".
Aynı zamanda, iki nesnenin sabit zaman ve istisnai güvenli değişimini sağlamak da yararlıdır. Bunun için sadece vücut nesnesine işaret eden işaretçinin değiştirilmesi gerekir.
Bir tutamaç, olmasını istediğiniz şeydir.
Bir tutamaç, bazı arama tablolarında kullanılan işaretsiz bir tamsayı olabilir.
Bir tutamaç, daha büyük bir veri kümesine veya bunun içine bir işaretçi olabilir.
Tanıtıcıyı kullanan kodun nasıl davrandığına bağlıdır. Bu, tutamaç tipini belirler.
Önemli olan, ' tutamaç ' teriminin kullanılmasının nedeni . Bu, onları bir kimlik veya erişim türü nesne olarak gösterir. Yani, programcı için bir 'anahtarı' veya bir şeye erişimi temsil ederler .
HANDLE hnd;
aynıdır void * ptr;
HANDLE, Visual Studio'daki (Windows) winnt.h dosyasında tanımlanan bir typedef'tir:
typedef void *HANDLE;
HANDLE hakkında daha fazla bilgi edinin