2017-06-04 184 views
0

我剛從這裏複製了一些代碼http://en.cppreference.com/w/cpp/language/pimpl,加了<memory>main.cpp,更正了std::experimental::propagate_const<std::unique_ptr<impl>>。 Visual Studio中2015年unique_ptr trouble? (VS 2015)

// widget.h 
#include <memory> 

class widget 
{ 
    // public members 
private: 
    struct impl; 
    std::unique_ptr<impl> pImpl; 
}; 

// widget.cpp 
#include "widget.h" 

struct widget::impl { 
    // implementation details 
}; 

widget.cpp編譯罰款,但main.cpp不是。

#include "widget.h" 

int main() 
{ 
    widget w; 
} 

錯誤消息。

1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1193): error C2027: use of undefined type 'widget::impl' 
1> e:\***\***\***\widget.h(8): note: see declaration of 'widget::impl' 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1192): note: while compiling class template member function 'void std::default_delete<_Ty>::operator()(_Ty *) noexcept const' 
1>   with 
1>   [ 
1>    _Ty=widget::impl 
1>   ] 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1397): note: see reference to function template instantiation 'void std::default_delete<_Ty>::operator()(_Ty *) noexcept const' being compiled 
1>   with 
1>   [ 
1>    _Ty=widget::impl 
1>   ] 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1227): note: see reference to class template instantiation 'std::default_delete<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=widget::impl 
1>   ] 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1236): note: see reference to class template instantiation 'std::_Get_deleter_pointer_type<_Ty,std::default_delete<_Ty>>' being compiled 
1>   with 
1>   [ 
1>    _Ty=widget::impl 
1>   ] 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1279): note: see reference to class template instantiation 'std::_Unique_ptr_base<_Ty,_Dx>' being compiled 
1>   with 
1>   [ 
1>    _Ty=widget::impl, 
1>    _Dx=std::default_delete<widget::impl> 
1>   ] 
1> e:\***\***\***\***.h(10): note: see reference to class template instantiation 'std::unique_ptr<widget::impl,std::default_delete<_Ty>>' being compiled 
1>   with 
1>   [ 
1>    _Ty=widget::impl 
1>   ] 
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1194): error C2338: can't delete an incomplete type 
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1195): warning C4150: deletion of pointer to incomplete type 'widget::impl'; no destructor called 
1> e:\***\***\***\widget.h(8): note: see declaration of 'widget::impl' 
+0

該cppreference頁面的底部有一個更完整的示例 – Cubbi

回答

0

問題是std::unique_ptr有一個與它關聯的刪除程序。如果未指定刪除者,則默認爲std::default_delete

它有什麼作用?它調用delete,這需要在此處定義析構函數。那需要在那裏定義。

+0

向'widget :: impl'添加了一個析構函數。依然沒有。 –

+0

@ J.Doe,你必須在'std:unique_ptr'的聲明之前添加它。 [實施例](https://godbolt.org/g/AMDjLR)。 – Incomputable

+0

但究竟如何? –

0

在單獨的cpp中定義Widget爲空的析構函數。在該cpp中包含impl的定義。 impl的析構函數在那個cpp中被調用,因爲你包含了定義。