Training
Modul
Auswählen des richtigen Datentyps in C#-Code - Training
Wählen Sie den richtigen Datentyp für Ihren Code aus mehreren grundlegenden Typen aus, die in C# verwendet werden.
Dieser Browser wird nicht mehr unterstützt.
Führen Sie ein Upgrade auf Microsoft Edge durch, um die neuesten Features, Sicherheitsupdates und den technischen Support zu nutzen.
In diesem Artikel wird gezeigt, wie Sie einen Nachverfolgungsverweis (%) in C++/CLI verwenden, um Common Language Runtime (CLR)-Typen nach Referenz zu übergeben.
Das folgende Beispiel zeigt, wie Sie einen Nachverfolgungsverweis verwenden, um CLR-Typen nach Verweis zu übergeben.
// tracking_reference_handles.cpp
// compile with: /clr
using namespace System;
ref struct City {
private:
Int16 zip_;
public:
City (int zip) : zip_(zip) {};
property Int16 zip {
Int16 get(void) {
return zip_;
} // get
} // property
};
void passByRef (City ^% myCity) {
// cast required so this pointer in City struct is "const City"
if (myCity->zip == 20100)
Console::WriteLine("zip == 20100");
else
Console::WriteLine("zip != 20100");
}
ref class G {
public:
int i;
};
void Test(int % i) {
i++;
}
int main() {
G ^ g1 = gcnew G;
G ^% g2 = g1;
g1 -> i = 12;
Test(g2->i); // g2->i will be changed in Test2()
City ^ Milano = gcnew City(20100);
passByRef(Milano);
}
zip == 20100
Das nächste Beispiel zeigt, dass das Übernehmen der Adresse eines Nachverfolgungsverweises eine interior_ptr (C++/CLI) zurückgibt und zeigt, wie Sie Daten über einen Nachverfolgungsverweis ändern und darauf zugreifen können.
// tracking_reference_data.cpp
// compile with: /clr
using namespace System;
public ref class R {
public:
R(int i) : m_i(i) {
Console::WriteLine("ctor: R(int)");
}
int m_i;
};
class N {
public:
N(int i) : m_i (i) {
Console::WriteLine("ctor: N(int i)");
}
int m_i;
};
int main() {
R ^hr = gcnew R('r');
R ^%thr = hr;
N n('n');
N %tn = n;
// Declare interior pointers
interior_ptr<R^> iphr = &thr;
interior_ptr<N> ipn = &tn;
// Modify data through interior pointer
(*iphr)->m_i = 1; // (*iphr)->m_i == thr->m_i
ipn->m_i = 4; // ipn->m_i == tn.m_i
++thr-> m_i; // hr->m_i == thr->m_i
++tn. m_i; // n.m_i == tn.m_i
++hr-> m_i; // (*iphr)->m_i == hr->m_i
++n. m_i; // ipn->m_i == n.m_i
}
ctor: R(int)
ctor: N(int i)
Das folgende Codebeispiel zeigt, dass Sie zwischen Tracking-Verweisen und Innenzeigern konvertieren können.
// tracking_reference_interior_ptr.cpp
// compile with: /clr
using namespace System;
public ref class R {
public:
R(int i) : m_i(i) {
Console::WriteLine("ctor: R(int)");
}
int m_i;
};
class N {
public:
N(int i) : m_i(i) {
Console::WriteLine("ctor: N(int i)");
}
int m_i;
};
int main() {
R ^hr = gcnew R('r');
N n('n');
R ^%thr = hr;
N %tn = n;
// Declare interior pointers
interior_ptr<R^> iphr = &hr;
interior_ptr<N> ipn = &n;
// Modify data through interior pointer
(*iphr)->m_i = 1; // (*iphr)-> m_i == thr->m_i
ipn->m_i = 4; // ipn->m_i == tn.m_i
++thr->m_i; // hr->m_i == thr->m_i
++tn.m_i; // n.m_i == tn.m_i
++hr->m_i; // (*iphr)->m_i == hr->m_i
++n.m_i; // ipn->m_i == n.m_i
}
ctor: R(int)
ctor: N(int i)
Dieses Beispiel zeigt ein einfaches Boxen durch einen Nachverfolgungsverweis auf einen Werttyp:
// tracking_reference_valuetypes_1.cpp
// compile with: /clr
using namespace System;
int main() {
int i = 10;
int % j = i;
Object ^ o = j; // j is implicitly boxed and assigned to o
}
Das nächste Beispiel zeigt, dass Sie sowohl Nachverfolgungsverweise als auch systemeigene Verweise auf Werttypen haben können.
// tracking_reference_valuetypes_2.cpp
// compile with: /clr
using namespace System;
int main() {
int i = 10;
int & j = i;
int % k = j;
i++; // 11
j++; // 12
k++; // 13
Console::WriteLine(i);
Console::WriteLine(j);
Console::WriteLine(k);
}
13
13
13
Das folgende Beispiel zeigt, dass Sie Nachverfolgungsverweise zusammen mit Werttypen und systemeigenen Typen verwenden können.
// tracking_reference_valuetypes_3.cpp
// compile with: /clr
value struct G {
int i;
};
struct H {
int i;
};
int main() {
G g;
G % v = g;
v.i = 4;
System::Console::WriteLine(v.i);
System::Console::WriteLine(g.i);
H h;
H % w = h;
w.i = 5;
System::Console::WriteLine(w.i);
System::Console::WriteLine(h.i);
}
4
4
5
5
In diesem Beispiel wird gezeigt, dass Sie einen Nachverfolgungsverweis auf einen Werttyp für den garbage-collection-Heap binden können:
// tracking_reference_valuetypes_4.cpp
// compile with: /clr
using namespace System;
value struct V {
int i;
};
void Test(V^ hV) { // hv boxes another copy of original V on GC heap
Console::WriteLine("Boxed new copy V: {0}", hV->i);
}
int main() {
V v; // V on the stack
v.i = 1;
V ^hV1 = v; // v is boxed and assigned to hV1
v.i = 2;
V % trV = *hV1; // trV is bound to boxed v, the v on the gc heap.
Console::WriteLine("Original V: {0}, Tracking reference to boxed V: {1}", v.i, trV.i);
V ^hV2 = trV; // hv2 boxes another copy of boxed v on the GC heap
hV2->i = 3;
Console::WriteLine("Tracking reference to boxed V: {0}", hV2->i);
Test(trV);
v.i = 4;
V ^% trhV = hV1; // creates tracking reference to boxed type handle
Console::WriteLine("Original V: {0}, Reference to handle of originally boxed V: {1}", v.i, trhV->i);
}
Original V: 2, Tracking reference to boxed V: 1
Tracking reference to boxed V: 3
Boxed new copy V: 1
Original V: 4, Reference to handle of originally boxed V: 1
Mithilfe eines Nachverfolgungsverweises in der Signatur einer Funktionsvorlage stellen Sie sicher, dass die Funktion von einem Parameter aufgerufen werden kann, dessen Typ systemeigener, CLR-Wert oder CLR-Verweis ist.
// tracking_reference_template.cpp
// compile with: /clr
using namespace System;
class Temp {
public:
// function templates
template<typename T>
static int f1(T% tt) { // works for object in any location
Console::WriteLine("T %");
return 0;
}
template<typename T>
static int f2(T& rt) { // won't work for object on the gc heap
Console::WriteLine("T &");
return 1;
}
};
// Class Definitions
ref struct R {
int i;
};
int main() {
R ^hr = gcnew R;
int i = 1;
Temp::f1(i); // ok
Temp::f1(hr->i); // ok
Temp::f2(i); // ok
// error can't track object on gc heap with a native reference
// Temp::f2(hr->i);
}
T %
T %
T &
Training
Modul
Auswählen des richtigen Datentyps in C#-Code - Training
Wählen Sie den richtigen Datentyp für Ihren Code aus mehreren grundlegenden Typen aus, die in C# verwendet werden.
Dokumentation
Weitere Informationen zu: C++/CLI-Aufgaben
C++-Stack-Semantik für Referenztypen
Weitere Informationen: C++-Stapelsemantik für Referenztypen
Reiner und überprüfbarer Code (C++/CLI)
Weitere Informationen zu: Reiner und nachweisbarer Code (C++/CLI)