免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6439 | 回复: 10
打印 上一主题 下一主题

为什么shared_ptr可以构造不完整的类型? 而unique_ptr不可以? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-29 14:27 |只看该作者 |倒序浏览
10可用积分
下面这一小段程序是编译不过去的,

  1. #include<memory>
  2. using namespace std;
  3. struct s;
  4. struct base{
  5.         //std::unique_ptr<s> ps;//编译不过
  6.         std::shared_ptr<s> ps;
  7. };
  8. int main()
  9. {   
  10.     base b;
  11.     return 0;
  12. }
复制代码
因为类型s没有被完整的定义,base b对象的析构函数里面unique_ptr无法delete s指针,因为s的析构函数不存在。
但是如果我改成shared_ptr就能编译过去。很奇怪的是,既然s的定义还没有出现,那么share_ptr的析构函数如何知道去删除一个s*呢?

请指点迷津!

最佳答案

查看完整内容

好吧,我错了……ISO C++1120.7.1.2.21 Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior,and shall not throw exceptions. [ Note: The use of default_delete requires T to be a complete type. —end note ]包括unique_ptr的析构函数在内的一些操作要求具有完整类型。居然看漏了这个另外google了一下,这里有和LZ相同的问题:http://stackoverflow.com/questions/60 ...

论坛徽章:
0
2 [报告]
发表于 2012-04-29 14:27 |只看该作者
好吧,我错了……
ISO C++11
20.7.1.2.2
1 Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior,
and shall not throw exceptions. [ Note: The use of default_delete requires T to be a complete type. —end note ]
包括unique_ptr的析构函数在内的一些操作要求具有完整类型。
居然看漏了这个
另外google了一下,这里有和LZ相同的问题:
http://stackoverflow.com/questio ... e-full-t-definition

论坛徽章:
0
3 [报告]
发表于 2012-04-29 15:11 |只看该作者
源码面前,了无秘密。

论坛徽章:
0
4 [报告]
发表于 2012-04-29 15:15 |只看该作者
本帖最后由 _Rayx 于 2012-04-29 15:16 编辑

回复 1# moonsister02
  1. unique_ptr (pointer __p)
  2. unique_ptr (pointer __p, typename std::conditional< std::is_reference< deleter_type >::value, deleter_type, const deleter_type & >::type __d)
  3. unique_ptr (pointer __p, typename std::remove_reference< deleter_type >::type &&__d)
  4. constexpr unique_ptr (nullptr_t)
  5. unique_ptr (unique_ptr &&__u)
  6. template<typename _Up , typename _Ep , typename = typename std::enable_if <std::is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value && !std::is_array<_Up>::value && ((std::is_reference<_Dp>::value && std::is_same<_Ep, _Dp>::value) || (!std::is_reference<_Dp>::value && std::is_convertible<_Ep, _Dp>::value))> ::type> unique_ptr (unique_ptr< _Up, _Ep > &&__u)
  7. unique_ptr (const unique_ptr &)
复制代码
  1. constexpr shared_ptr ()
  2. template<typename _Tp1 > shared_ptr (_Tp1 *__p)
  3. template<typename _Tp1 , typename _Deleter > shared_ptr (_Tp1 *__p, _Deleter __d)
  4. template<typename _Deleter > shared_ptr (nullptr_t __p, _Deleter __d)
  5. template<typename _Tp1 , typename _Deleter , typename _Alloc > shared_ptr (_Tp1 *__p, _Deleter __d, _Alloc __a)
  6. template<typename _Deleter , typename _Alloc > shared_ptr (nullptr_t __p, _Deleter __d, _Alloc __a)
  7. template<typename _Tp1 > shared_ptr (const shared_ptr< _Tp1 > &__r, _Tp *__p)
  8. template<typename _Tp1 , typename = typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> shared_ptr (const shared_ptr< _Tp1 > &__r)
  9. shared_ptr (shared_ptr &&__r)
  10. template<typename _Tp1 , typename = typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> shared_ptr (shared_ptr< _Tp1 > &&__r)
  11. template<typename _Tp1 > shared_ptr (const weak_ptr< _Tp1 > &__r)
  12. template<typename _Tp1 , typename _Del > shared_ptr (std::unique_ptr< _Tp1, _Del > &&__r)
  13. constexpr shared_ptr (nullptr_t __p)
复制代码

论坛徽章:
0
5 [报告]
发表于 2012-04-29 18:17 |只看该作者
实现的bug。
ISO C++11 20.7.1
5 Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable. The template parameter T of unique_ptr may be an incomplete type.

论坛徽章:
0
6 [报告]
发表于 2012-04-30 09:36 |只看该作者
幻の上帝 发表于 2012-04-29 18:17
实现的bug。
ISO C++11 20.7.1
5 Each object of a type U instantiated from the unique_ptr template s ...


你的意思是说,其实unqiue_ptr也可以作用于不完整的类型? 标准里面不应该有maybe这样的字眼吧,标准应该是确定的?

论坛徽章:
0
7 [报告]
发表于 2012-04-30 10:02 |只看该作者
moonsister02 发表于 2012-04-30 09:36
你的意思是说,其实unqiue_ptr也可以作用于不完整的类型? 标准里面不应该有maybe这样的字眼吧,标准应该 ...


看我的回答,unique_ptr根本没有默认的构造函数!unique_ptr<s> ps就找不到这样的函数,试试unique_ptr<s> ps(nullptr_t);

论坛徽章:
0
8 [报告]
发表于 2012-04-30 13:02 |只看该作者
回复 5# moonsister02

may be不是maybe,表示准许。
符合ISO/IEC Directives, Part 3对规范用词的要求。

Annex E
(normative)
Verbal forms for the expression of provisions
...
Table E.1 — Requirement
Verbal form Equivalent expressions for use in exceptional cases
(see 6.6.1.3)
shall is to
is required to
it is required that
has to
only … is permitted
it is necessary
shall not is not allowed [permitted] [acceptable] [permissible]
is required to be not
is required that … be not
is not to be
Do not use “must” as an alternative for “shall”. (This will avoid any confusion
between the requirements of a standard and external statutory obligations.)
Do not use “may not” instead of “shall not” to express a prohibition.
To express a direct instruction, for example referring to steps to be taken in a test
method, use the imperative mood in English.
EXAMPLE “Switch on the recorder.”
...
Table E.2 — Recommendation
Verbal form Equivalent expressions for use in exceptional cases
(see 6.6.1.3)
should it is recommended that
ought to
should not it is not recommended that
ought not to
In French, do not use “devrait” in this context.
...
Table E.3 — Permission
Verbal form Equivalent expressions for use in exceptional cases
(see 6.6.1.3)
may is permitted
is allowed
is permissible
need not it is not required that
no … is required
Table E.4 — Possibility and capability
Verbal form Equivalent expressions for use in exceptional cases
(see 6.6.1.3)
can be able to
there is a possibility of
it is possible to
cannot be unable to
there is no possibility of
it is not possible to
NOTE See note 1 to Table E.3.

原文是表格,在左边的加粗了。

论坛徽章:
0
9 [报告]
发表于 2012-04-30 13:04 |只看该作者
回复 6# _Rayx
你又错了。
ISO C++11
20.7.1.2.1 unique_ptr constructors [unique.ptr.single.ctor]
constexpr unique_ptr() noexcept;
1 Requires: D shall satisfy the requirements of DefaultConstructible (Table 19), and that construction shall not throw an exception.
2 Effects: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.
3 Postconditions: get() == nullptr. get_deleter() returns a reference to the stored deleter.
4 Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed.

论坛徽章:
0
10 [报告]
发表于 2012-04-30 13:24 |只看该作者
回复 8# 幻の上帝


    看了一下文头件,还真有。我错了。
  1. 00114       constexpr unique_ptr()
  2. 00115       : _M_t()
  3. 00116       { static_assert(!std::is_pointer<deleter_type>::value,
  4. 00117              "constructed with null function pointer deleter"); }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP