我刚从这里复制了一些代码http://en.cppreference.com/w/cpp/language/pimpl,添加了<memory>
和main.cpp
,更正了std::experimental::propagate_const<std::unique_ptr<impl>>
。 Visual Studio 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 :(得分:0)
问题是std::unique_ptr
有一个与之关联的删除者。如果未指定删除者,则默认为std::default_delete
。
它做了什么?它在其上调用delete
,这需要在该点定义析构函数。这需要在那里定义。
答案 1 :(得分:0)
在单独的cpp中定义Widget的析构函数为空。在cpp中包含impl的定义。 impl的析构函数在cpp中调用,因为你包含了定义。