【问题标题】:Dereference unique_ptr to a reference取消引用 unique_ptr 到引用
【发布时间】:2019-10-29 10:04:57
【问题描述】:

以下(不安全的)代码有效

#include <iostream>
#include <fstream>

std::ofstream* create_unsafe_stream(const char* filename) {
    return new std::ofstream {filename};
}

int main () {
    std::ofstream& u_out = *create_unsafe_stream("foo.txt");
    u_out << "foo\n" ;
    delete &u_out;
    return 0;
}

我试图制作一个更安全的版本

#include <iostream>
#include <fstream>
#include <memory>

using stream_ptr = std::unique_ptr<std::ostream>;

stream_ptr create_safe_stream(const char* filename) {
    return stream_ptr{ new std::ofstream {filename}};
}

int main() {
  std::ostream& s_out = *create_safe_stream("foo.txt");
  s_out << "foo\n" << std::endl; 
  return 0
}

哪个编译但是,当我运行它时给我一个分段错误。我在想问题是由unique_ptr 超出范围引起的。所以我尝试将main 修改为

int main() {
   stream_ptr ofile = create_safe_stream("foo.txt");
   std::ostream& s_out = *ofile;
   s_out << "foo\n"; 
}

再次起作用。

问题

有没有办法不使用像ofile 这样的“中间”变量并在一行中执行所有操作?

编辑

函数create_safe_streamwhat I want的玩具模型,也就是说这个函数可能返回std::ofstream到那个文件或者std::cout,所以我想我真的需要返回一个指向基址的指针类std::ostream。我该怎么办?

【问题讨论】:

  • (编辑后):ofile 不是中间的,它是对象的 OWNER。而s_out 是所包含对象的辅助别名。

标签: c++ c++11 segmentation-fault unique-ptr dereference


【解决方案1】:

你的假设是正确的。 create_safe_stream 返回一个 std::unique_ptr ,它立即超出范围,因此它拥有的原始资源是 deleted 并且尝试使用它是 UB。

不使用中间变量并在一行中完成所有操作的方法是只返回一个std::ofstream 对象:

std::ofstream create_safe_stream(const char* filename) {
    return std::ofstream {filename};
}

int main() {
  std::ostream s_out = create_safe_stream("foo.txt");
  s_out << "foo\n" << std::endl; 
  return 0;
}

【讨论】:

  • 感谢您的回答。然而,我写的是我的问题的“玩具模型”。实际上函数create_safe_stream 应该打开文件或重定向std::out(如stackoverflow.com/questions/56521318/…),因此我认为我确实需要返回指向std::ostream 的指针。有没有办法做到这一点?
  • 你仍然需要持有智能指针,但在这种情况下你可以做的一个技巧是返回一个std::unique_ptr&lt;std::osteram, std::function&lt;void(std::ostream*)&gt;&gt;,你可以在其中删除[](std::ostream* os) { delete os; },或者如果你要返回指向std::cout 的指针,删除器是 nop。 (为了获得最佳性能,请不要使用 std::function,但希望您能理解。)
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 2023-03-23
  • 2016-11-18
  • 2012-06-24
  • 1970-01-01
相关资源
最近更新 更多