İşlenecek Nesne İşleci (^) (C++/CLI ve C++/CX)
Tanıtıcı bildirimcisi ("^
hat" olarak okunur), sistem nesnenin artık erişilebilir olmadığını belirlediğinde bildirilen nesnenin otomatik olarak silinmesi gerektiği anlamına gelen tür tanımlayıcısını değiştirir.
Bildirilen Nesneye Erişme
Tanıtıcı bildirimcisi ile bildirilen bir değişken, nesneye yönelik bir işaretçi gibi davranır. Ancak değişken nesnenin tamamına işaret eder, nesnenin bir üyesine işaret edemez ve işaretçi aritmetiğini desteklemez. Nesneye erişmek için dolaylı işlecini (*
) ve nesnenin bir üyesine erişmek için ok üye erişim işlecini (->
) kullanın.
Windows Çalışma Zamanı
Derleyici, nesnenin artık kullanılmadığını ve silinip silinemediğini belirlemek için COM başvuru sayma mekanizmasını kullanır. Bu mümkündür çünkü Windows Çalışma Zamanı arabiriminden türetilen bir nesne aslında bir COM nesnesidir. Nesne oluşturulduğunda veya kopyalandığında başvuru sayısı artırılır ve nesne null olarak ayarlandığında veya kapsam dışına çıktığında azalmıştır. Başvuru sayısı sıfıra çıkarsa nesne otomatik olarak ve hemen silinir.
Tanıtıcı bildirimcinin avantajı, COM'da yorucu ve hataya açık bir işlem olan nesnenin başvuru sayısını açıkça yönetmeniz gerektiğidir. Diğer bir ifadeyle, başvuru sayısını artırmak ve azaltmak için nesnenin AddRef() ve Release() yöntemlerini çağırmanız gerekir. Bununla birlikte, tanıtıcı bildirimci ile bir nesne bildirirseniz, derleyici başvuru sayısını otomatik olarak ayarlayan kod oluşturur.
Bir nesnenin örneğini oluşturma hakkında bilgi için bkz . ref new.
Gereksinimler
Derleyici seçeneği: /ZW
Ortak Dil Çalışma Zamanı
Sistem, nesnenin artık kullanılmadığını ve silinip silinemediğini belirlemek için CLR çöp toplayıcı mekanizmasını kullanır. Ortak dil çalışma zamanı, nesneleri ayırdığı bir yığın tutar ve programınızdaki yönetilen başvuruları (değişkenler) kullanarak yığındaki nesnelerin konumunu belirtir. Bir nesne artık kullanılmadığında, yığında kapladığında bellek boşaltılır. Düzenli aralıklarla, atık toplayıcı boşaltılan belleği daha iyi kullanmak için yığını sıkıştırıyor. Yığının sıkıştırılması, yığındaki nesneleri taşıyabilir ve bu da yönetilen başvurular tarafından başvurulan konumları geçersiz kılabilir. Ancak, çöp toplayıcı tüm yönetilen başvuruların konumunun farkındadır ve bunları yığındaki nesnelerin geçerli konumunu gösterecek şekilde otomatik olarak güncelleştirir.
Yerel C++ işaretçileri (*
) ve başvuruları (&
) yönetilen başvurular olmadığından, çöp toplayıcı işaret ettiği adresleri otomatik olarak güncelleştiremez. Bu sorunu çözmek için, çöp toplayıcının farkında olduğu ve otomatik olarak güncelleştirilebileceği bir değişken belirtmek için tanıtıcı bildirimcisini kullanın.
Daha fazla bilgi için bkz . Nasıl yapılır: Yerel Türlerde Tanıtıcıları Bildirme.
Örnekler
Bu örnek, yönetilen yığında bir başvuru türünün örneğinin nasıl oluşturulacağını gösterir. Bu örnek ayrıca bir tanıtıcıyı başka bir tanıtıcıyla başlatabileceğinizi gösterir ve bu da yönetilen, çöp olarak toplanan yığında aynı nesneye iki başvuruyla sonuçlanır. Bir tanıtıcıya nullptr atamanın nesneyi çöp toplama için işaretlemediğini görebilirsiniz.
// mcppv2_handle.cpp
// compile with: /clr
ref class MyClass {
public:
MyClass() : i(){}
int i;
void Test() {
i++;
System::Console::WriteLine(i);
}
};
int main() {
MyClass ^ p_MyClass = gcnew MyClass;
p_MyClass->Test();
MyClass ^ p_MyClass2;
p_MyClass2 = p_MyClass;
p_MyClass = nullptr;
p_MyClass2->Test();
}
1
2
Aşağıdaki örnekte yönetilen yığındaki bir nesneye tanıtıcının nasıl bildirileceği gösterilmektedir; burada nesne türü kutulanmış bir değer türüdür. Örnek ayrıca kutulu nesneden değer türünün nasıl alınacaklarını da gösterir.
// mcppv2_handle_2.cpp
// compile with: /clr
using namespace System;
void Test(Object^ o) {
Int32^ i = dynamic_cast<Int32^>(o);
if(i)
Console::WriteLine(i);
else
Console::WriteLine("Not a boxed int");
}
int main() {
String^ str = "test";
Test(str);
int n = 100;
Test(n);
}
Not a boxed int
100
Bu örnek, rastgele bir nesneye işaret eden bir void*
işaretçi kullanmanın yaygın C++ deyiminin, herhangi bir başvuru sınıfına tanıtıcı tutabilen ile değiştirildiğini Object^
gösterir. Ayrıca diziler ve temsilciler gibi tüm türlerin bir nesne tanıtıcısına dönüştürülebileceğini gösterir.
// mcppv2_handle_3.cpp
// compile with: /clr
using namespace System;
using namespace System::Collections;
public delegate void MyDel();
ref class MyClass {
public:
void Test() {}
};
void Test(Object ^ x) {
Console::WriteLine("Type is {0}", x->GetType());
}
int main() {
// handle to Object can hold any ref type
Object ^ h_MyClass = gcnew MyClass;
ArrayList ^ arr = gcnew ArrayList();
arr->Add(gcnew MyClass);
h_MyClass = dynamic_cast<MyClass ^>(arr[0]);
Test(arr);
Int32 ^ bi = 1;
Test(bi);
MyClass ^ h_MyClass2 = gcnew MyClass;
MyDel^ DelInst = gcnew MyDel(h_MyClass2, &MyClass::Test);
Test(DelInst);
}
Type is System.Collections.ArrayList
Type is System.Int32
Type is MyDel
Bu örnek, bir tanıtıcının başvurulabildiğini ve üyeye başvurulmamış tanıtıcı aracılığıyla erişilebileceğini gösterir.
// mcppv2_handle_4.cpp
// compile with: /clr
using namespace System;
value struct DataCollection {
private:
int Size;
array<String^>^ x;
public:
DataCollection(int i) : Size(i) {
x = gcnew array<String^>(Size);
for (int i = 0 ; i < Size ; i++)
x[i] = i.ToString();
}
void f(int Item) {
if (Item >= Size)
{
System::Console::WriteLine("Cannot access array element {0}, size is {1}", Item, Size);
return;
}
else
System::Console::WriteLine("Array value: {0}", x[Item]);
}
};
void f(DataCollection y, int Item) {
y.f(Item);
}
int main() {
DataCollection ^ a = gcnew DataCollection(10);
f(*a, 7); // dereference a handle, return handle's object
(*a).f(11); // access member via dereferenced handle
}
Array value: 7
Cannot access array element 11, size is 10
Bu örnek, int
yerel başvurunun (&
) toplanan çöp yığınında depolanabileceği ve yerel başvuruların yönetilen yığındaki nesne hareketini izlemediği için yönetilen türün bir üyesine bağlanamazsınızint
. Düzeltme, yerel bir değişken kullanmak veya olarak değiştirmektir &
%
ve bunu bir izleme başvurusu haline getirir.
// mcppv2_handle_5.cpp
// compile with: /clr
ref struct A {
void Test(unsigned int &){}
void Test2(unsigned int %){}
unsigned int i;
};
int main() {
A a;
a.i = 9;
a.Test(a.i); // C2664
a.Test2(a.i); // OK
unsigned int j = 0;
a.Test(j); // OK
}
Gereksinimler
Derleyici seçeneği: /clr