2016-12-10 42 views
1

アドバイスhereに基づいてネイティブC++型をラップするために使用できるC++/CLIでrefクラステンプレートを作成しようとしています。これは私がこれまで持っているものです。警告C4150ネイティブ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

デストラクタは実際にここで呼び出すことはできないと思います。あなたの設計上の問題は、MyNativeClassを前方宣言すると、ネイティブラッパーとpimplイディオムを組み合わせようとしていることです.pimplイディオムはテンプレート化できません。 – Eugene

+0

@Eugeneは、テンプレート化され、pimplイディオムで使用できる 'shared_ptr'や' unique_ptr'に似たこのラッパーではありません。 – user3467895

答えて

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

だから、私はそれがOKであると仮定します。

なぜ私は完全に理解しているのか分かりません。 thisによれば、スタックセマンティクスを使用して参照型のインスタンスを作成すると、コンパイラは(gcnewを使用して)ガベージコレクションヒープ上にインスタンスを内部的に作成します。

関連する問題