我试图在C ++ / CLI中编写一个ref类模板,该模板可用于根据建议here包装本机C ++类型。这就是我到目前为止所做的:
template<class T>
public ref class NativeWrapper {
T* ptr_;
protected:
!NativeWrapper() { delete ptr_; } // <-- C4150 Warning here!
public:
NativeWrapper(std::unique_ptr<T> ptr) : ptr_(ptr.release()) {}
T* get() { return ptr_; }
T* operator->() { return ptr_; }
~NativeWrapper() { NativeWrapper::!NativeWrapper(); }
};
然后我想将它用作ref类中的成员但我想在.h文件中使用本机类的前向声明:
// MyManagedClass.h
#include "NativeWrapper.h"
// forward declaration
class MyNativeClass;
ref class MyManagedClass {
NativeWrapper<MyNativeClass> my_native_class_;
public:
MyManagedClass();
void doSomething();
};
// MyManagedClass.cpp
#include "MyManagedClass.h"
#include "MyNativeClass.h"
MyManagedClass::MyManagedClass() : my_native_class_(std::make_unique<MyNativeClass>()) { }
void MyManagedClass::doSomething() {
my_native_class->doSomething();
}
本机类的析构函数似乎被正确调用,但我收到以下警告:
Warning C4150 deletion of pointer to incomplete type 'MyNativeClass'; no destructor called
请参阅上面一行的注释。
我已尝试在MyManagedClass.cpp
中明确编写析构函数和终结函数,如果我在本机c ++中遇到类似问题但我似乎无法解决问题。
答案 0 :(得分:0)
我发现如果我使成员成为句柄而不是使用堆栈语义,那么我就不会再收到警告了:
// MyManagedClass.h
#include "NativeWrapper.h"
// forward declaration
class MyNativeClass;
ref class MyManagedClass {
NativeWrapper<MyNativeClass>^ my_native_class_;
public:
MyManagedClass();
void doSomething();
};
// MyManagedClass.cpp
#include "MyManagedClass.h"
#include "MyNativeClass.h"
MyManagedClass::MyManagedClass()
: my_native_class_(gcnew NativeWrapper<MyNativeClass>((std::make_unique<MyNativeClass>())) { }
void MyManagedClass::doSomething() {
my_native_class->doSomething();
}
所以,我认为没问题。
我不确定我完全理解为什么。根据{{3}}“当您使用堆栈语义创建引用类型的实例时,编译器会在垃圾收集堆上内部创建实例(使用gcnew)”。