我用下面的兩個容器中的一個時,與垃圾收集友好的互操作是首選:
template<typename T> ref class GcPlainPtr sealed {
T* ptr;
public:
GcPlainPtr(T*ptr): ptr(ptr) { GC::AddMemoryPressure(sizeof(T)); }
!GcPlainPtr() {
GC::RemoveMemoryPressure(sizeof(T));
delete ptr; ptr = nullptr;
}
~GcPlainPtr() { this->!GcPlainPtr(); } //mostly just to avoid C4461
T* get() {return ptr;}
static T* operator->(GcPlainPtr<T>% gcPtr) { return gcPtr.ptr;}
static operator T*(GcPlainPtr<T>% gcPtr) { return gcPtr.ptr; }
};
上一個容器看起來足以滿足您的需求。
ref class MyManagedClass {
GcPlainPtr<userData> myUserData;
MyManagedClass(...bla...)
: myUserData(new userData(...))
, ...
{...}
AnotherMethod() {
std::cout << myUserData->data1 << '\n';
AddItem(1, myUserData.get());
}
}
前一種方法的優點是,即使你忘記處置的對象,內存壓力,合理更新,垃圾收集發生在適當的頻率:您可以按如下方式使用它。
如果你知道你roughtly分配數據元素的大小,但它不僅是直接的大小(即原生結構或類內部分配內存),下面的變體可能更合適:
template<typename T> ref class GcAutoPtr sealed {
T* ptr;
size_t size;
public:
GcAutoPtr(T*ptr,size_t size) : ptr(ptr), size(size) {
GC::AddMemoryPressure(size);
}
!GcAutoPtr() {
GC::RemoveMemoryPressure(size);
size=0;
delete ptr;
ptr = nullptr;
}
~GcAutoPtr() { this->!GcAutoPtr();} //mostly just to avoid C4461
T* get() {return ptr;}
static T* operator->(GcAutoPtr<T>% gcPtr) { return gcPtr.ptr;}
static operator T*(GcAutoPtr<T>% gcPtr) { return gcPtr.ptr; }
};