当前位置:  开发笔记 > 编程语言 > 正文

为什么std :: unique_ptr没有像std :: shared_ptr这样的别名构造函数?

如何解决《为什么std::unique_ptr没有像std::shared_ptr这样的别名构造函数?》经验,为你挑选了2个好方法。

我刚刚发现了std::shared_ptr"别名构造函数"并发现自己在问"为什么std :: unique_ptr没有相应的一个?

也就是说,如果你想分配一个Foo你可以把它的Bar成员传递给一个应该完全管理它的生命周期的函数Foo,那么能不能这样做吗?

#include 

struct B {}
struct A {
  B b;
}

void f(std::unique_ptr b);

std::unique_ptr a = std::make_unique();
std::unique_ptr b { std::move(a), &(a->b) };  // a now invalid.
f(std::move(b));  // f now responsible for deleting the A.

这适用于std :: shared_ptr(http://ideone.com/pDK1bc)

#include 
#include 
#include 

struct B {
  std::string s;
};
struct A {
  B b;
  A(std::string s) : b{s} {};
  ~A() { std::cout << "A deleted." << std::endl; }
};

void f(std::shared_ptr b) {
  std::cout << "in f, b->s = " << b->s << " (use_count=" << b.use_count() << ")" << std::endl;
}

int main() {
  std::shared_ptr a = std::make_shared("hello");
  std::shared_ptr b { a, &(a->b) };
  a.reset();  // a now invalid.
  std::cout << "before f, b->s = " << b->s << " (use_count=" << b.use_count() << ")" << std::endl;
  f(std::move(b));  // f now responsible for deleting the A.
  std::cout << "after f" << std::endl;
  return 0;
}

输出预期的

before f, b->s = hello (use_count=1)
in f, b->s = hello (use_count=1)
A deleted.
after f

有没有合理的理由说明为什么不包含这样的东西?和/或,unique_ptr使用自定义删除器删除A?来模拟它是不是一个坏主意?



1> 5gon12eder..:

我相信"问题"是,不像std::shared_ptr,std::unique_ptr删除器不是类型擦除的.默认删除器std::unique_ptr(其大小为零,编码为类型本身作为几乎不可见的默认类型参数)很简单[](T * p){ delete p; }.但很明显,通过指向对象成员std::unique_ptr创建的那个std::make_unique和通过指向对象B成员创建的那个A不能具有相同的删除器.后一种情况的删除器必须做一些指针运算才能获得原始A *指针.如果两个删除器都存储偏移量或内部指针指向原始对象,那么这两个删除器只能具有相同的类型.那将不再是零大小.std::unique_ptr与做newdelete手动相比,设计的开销为零,这是一件好事.我没有看到使用你自己的删除器存储额外的指针的任何直接的缺点,虽然我仍然需要遇到一个用例,我发现这有用.



2> Yakk - Adam ..:

shared_ptr有引用计数开销.在它的引用计数块中,它还存储一个显式的删除器(因为如果你在堆上存储,还有几个字节?)

这也是为什么shared_ptr基类型可以记住在没有虚拟dtor的情况下删除派生类型的原因.

unique_ptr另一方面,它将删除器存储在实例中,默认删除器是无状态的 - 使用0个字节.unique_ptr就内存使用而言,这会使原始指针的开销为零.

无状态删除者不记得删除别的东西.

您可以添加一个unique_ptr支持别名的有状态删除器,但是您必须手动设置别名.其中一个构造函数同时使用指针和删除器.

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有