我用下面的两个容器中的一个时,与垃圾收集友好的互操作是首选:
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; }
};