警告C4150在尝试包装本机C 类时,指向不完整类型的指针删除

Warning C4150 deletion of pointer to incomplete type when trying to wrap native c++ class

本文关键字:类型 删除 指针 C4150 包装 类时 本机 警告      更新时间:2023-10-16

我正在尝试在C /CLI中编写一个REF类模板,该模板可根据此处的建议来用来包装本机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中明确编写destructor和cinterizer,这是我在本机C 中遇到类似问题的情况,但似乎并不能解决问题。

我发现,如果我使成员成为手柄而不是使用堆栈语义,那么我再也不会收到警告:

// 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();
}

所以,我认为还可以。

我不确定我是否完全理解原因。根据此,"当您使用堆栈语义创建参考类型的实例时,编译器确实在收集的垃圾(使用GCNew)上创建实例。