GotW#101“溶液”实际上解决什么? [英] Does the GotW #101 "solution" actually solve anything?

查看:152
本文介绍了GotW#101“溶液”实际上解决什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先阅读Herb's Sutters在C ++ 11中有关pimpl的帖子:

First read Herb's Sutters GotW posts concerning pimpl in C++11:

GotW#101:编译防火墙,第2部分(难度:8/10)

我在理解GotW#101中提出的解决方案时遇到一些麻烦。据我所知,在GotW#100中艰苦地解决的所有问题都回到了复仇之中:

I'm having some trouble understanding the solution proposed in GotW #101. As far as I can understand, all the problems laboriously solved in GotW #100 are back with a vengeance:


  • c $ c> pimpl 成员是超出范围的模板,并且定义在使用时不可见(在类窗口小部件 s类定义和隐式生成 widget 的特殊成员函数。也没有任何明确的实例化。这将导致链接期间出现未解决的外部错误。

  • The pimpl members are out-of-line templates, and the definitions are not visible at the point of use (in class widget's class definition and implicitly generated special member functions of widget). There aren't any explicit instantiations either. This will cause unresolved external errors during linking.

widget :: impl 其中 pimpl< widget :: impl> ::〜pimpl()实例化定义(我不认为它实际上是实例化,只是参考)。因此 std :: unique_ptr< widget :: impl> ::〜unique_ptr()调用 delete 如果 widget :: impl 有一个非平凡的析构函数,它会产生未定义的行为。

widget::impl is still incomplete at the point where pimpl<widget::impl>::~pimpl() is instantiated defined (I don't think it actually IS instantiated at all, just referenced). So std::unique_ptr<widget::impl>::~unique_ptr() calls delete on a pointer to incomplete type, which produces undefined behavior if widget::impl has a non-trivial destructor.

请解释强制编译器在 widget :: impl 完成的上下文中生成特殊成员的原因。

Please explain what forces the compiler to generate the special members in a context where widget::impl is complete. Because I can't see how this works.

如果GotW#101仍然需要明确定义 widget ::〜widget()在实现文件中,其中 widget :: impl 完成后,请解释更鲁棒 (在他的回答中引用的)。

If GotW #101 still requires explicit definition of widget::~widget() in the implementation file, where widget::impl is complete, then please explain the "More Robust" comment (which @sehe quoted in his answer).

我正在查看GotW#101的核心声明,包装器消除了一些样板对我来说(基于段落的其余部分)意味着 widget ::〜widget()声明和定义。所以,请不要依赖于你的答案,在GotW#101,这已经走了!

I'm looking at the core claim of GotW #101 that the wrapper "eliminates some pieces of boilerplate", which seems to me (based on the remainder of the paragraph) to mean the widget::~widget() declaration and definition. So please don't rely on that in your answer, in GotW #101, that's gone!

草药

推荐答案

你是正确;该示例似乎缺少一个显式模板实例化。当我尝试在MSVC 2010 SP1上使用 widget :: impl 的构造函数和析构函数运行示例时,我收到一个链接器错误 pimpl< widget :: impl> :: pimpl() pimpl< widget :: impl> ::〜pimpl()。当我添加模板类pimpl< widget :: impl> ;; 时,它链接正常。

You are correct; the example seems to be missing an explicit template instantiation. When I try to run the example with a constructor and destructor for widget::impl on MSVC 2010 SP1, I get a linker error for pimpl<widget::impl>::pimpl() and pimpl<widget::impl>::~pimpl(). When I add template class pimpl<widget::impl>;, it links fine.

GotW#101从GotW#100中删除了所有的样板,但是你需要添加一个显式的实例化 pimpl< ...> $ c> pimpl impl。至少用#101你需要的锅炉板很简单。

In other words, GotW #101 eliminates all boilerplate from GotW #100, but you need to add an explicit instantiation of the pimpl<...> template with the implementation of the pimpl impl. At least with #101 the boiler plate you need is straightforward.

这篇关于GotW#101“溶液”实际上解决什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆