将unique_ptr取消引用到引用

时间:2019-06-14 18:52:39

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

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

#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_streamverify it的玩具模型,也就是说,该函数可能将std::ofstream返回到该文件或std::cout,所以我认为需要返回一个指向基类std::ostream的指针。我该怎么办?

1 个答案:

答案 0 :(得分:3)

您的假设是正确的。 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;
}