【问题标题】:How to create a reference to a smart_pointer?如何创建对 smart_pointer 的引用?
【发布时间】:2020-01-09 04:37:16
【问题描述】:
std::ofstream x; 
std::ostream *foo = NULL; 
x.open(...); 
foo = &x; 
std::ostream *bar = diff? foo2() : foo; //foo2 is a function returning a new std::ostream(...) and has no side effects
std::ostream &bar1 = *foo; 
std::ostream &bar2 = *bar; 

这里,bar 选择性地是不需要删除的指针 (foo) 或使用 new 创建的需要删除的指针 (foo2())。

我想让 bar 成为一个智能指针(可能 shared_ptr 在这里最有意义)所以我不必显式处理删除,以防 foo2 的结果被分配给它。

但这意味着我也将 foo(并使 foo2 返回)设为 shared_ptr,因为除非我这样做,否则我会得到一个

free(): invalid pointer
free(): invalid pointer

错误。

std::shared_ptr<std::ostream> foo2(..) {
   ...
   std::shared_ptr<std::ostream> ptr(new std::ofstream(...));
   return ptr;
}

...

std::ofstream x; 
std::shared_ptr<std::ostream> foo(nullptr); 
x.open(...); 
foo.reset(&x); 
std::shared_ptr<std::ostream> bar(diff? foo2() : foo); 
std::ostream &bar1 = *foo; 
std::ostream &bar2 = *bar; 

现在,我收到了这个错误 -

munmap_chunk(): invalid pointer
free(): invalid pointer

乍一看,我认为让 bar1 和 bar2 共享_ptrs 可能会解决问题,但考虑到 bar1 和 bar2 是对 foo 和 bar 的引用,我不确定如何做到这一点。有人可以帮我解决这个问题吗?

【问题讨论】:

  • 请出示完整的minimal reproducible example
  • “但是,即使在这样做之后,我也会遇到同样的错误。” 请告诉我们你是如何做到的
  • 你希望它在它无法知道的情况下以某种方式知道它何时可以删除。不管你选择什么类型。
  • @DeanSeo 我更新了帖子,尝试将 foo、bar 和 foo2()(返回)一个 shared_ptr。
  • @walnut 正如 eerorika 在回答中所解释的那样,您不能拥有一个 unique_ptr 或 shared_ptr 的有条件拥有的指针(即有时拥有,有时不拥有)。对于 unique_ptr 或 shared_ptr 你必须知道你是否拥有它。然后,当您知道这一点时,您可以选择如何管理它。中间没有。

标签: c++ smart-pointers


【解决方案1】:

bar 选择性地是一个不需要删除的指针...或一个需要删除的指针...

我想让 bar 成为智能指针

这是一个糟糕的设计。最好使用无条件拥有或无条件非拥有指针,而不是有条件地使用其中一个。

我建议您将使用 ostream 的所有内容移到单独的函数中,然后使用一个流或另一个简单地调用它:

void use_stream(std::ostream&);

if (diff) {
    auto ptr = foo2(); // some flavour of smart pointer
                       // use unique if you don't need shared
    use_stream(*ptr);
} else {
    std::ofstream foo(...);
    use_stream(foo);
}

但是,最好从foo2 按值返回流,除非您出于某种动态多态性原因使用间接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-26
    • 2016-06-04
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多