c++ - 使用文件描述符移动对象

标签 c++

我有一节课,说Foo ,定义如下:

class Foo {
public:
  Foo(int i) {
    valid = false;
    char devname[] = "/dev/device0";
    sprintf(devname, "/dev/device%d", i);
    fd = open(devname, O_RDWR);
    if (fd > 0) {
      valid = true;
    }

  ~Foo() {
    if (valid) {
      close(fd);
    }
  }

  bool valid;
private:
  int fd;
};

我还有一个类(class),比如说Bar ,定义如下:

class Bar {
public:
  Bar() {
    for (int i = 0; i < 4; i++) {
      Foo foo(i);
      if (foo.valid) {
        vector_of_foos.push_back(foo);
      }
    }
  }

  std::vector<Foo> vector_of_foos;
};

问题在于 push_back复制 Foo 对象,复制 fd属性(property)。然后是原始 Foo 的析构函数对象被调用,它关闭了 fd 的文件指向,渲染fd无效。

不幸的是我不能使用emplace_back因为我需要实例化我的 Foo对象 before 添加到 vector_of_foos vector ,以便我可以检查 valid属性(property)。

我也尝试过使用 std::move但这仍然调用原始 Foo 的析构函数对象一旦超出范围就会关闭文件。

管理这样的资源的推荐方法是什么?我应该使用智能指针数组吗?应该是我的vector_of_foos改为 std::vector<Foo *>我在其中维护指向 Foo 的指针 vector 我动态分配哪个?

最佳答案

Foo 需要复制构造函数和复制赋值运算符,因此它可以 dup() 复制源对象的 fd(或者,您需要删除它们,这样Foo 对象根本无法复制,只能移动)。

在实现移动语义时,将 fd 值从移出对象移动到移入对象后,需要更新移出对象,使其 fd 不再引用有效的文件描述符。只需将它设置为 -1,这是 open()dup() 返回的错误。

您根本不需要您的有效 成员。如果它与您的 fd 不同步,这就是等待发生的错误来源。

尝试更像这样的东西:

class Foo {
public:
  Foo(int i) {
    std::string devname = "/dev/device" + std::to_string(i);
    fd = open(devname.c_str(), O_RDWR);
  }

  Foo(const Foo &src) {
    fd = dup(src.fd);
  }
  // or: Foo(const Foo &) = delete;

  Foo(Foo &&src) : fd(-1) {
    src.swap(*this);
  }

  ~Foo() {
    if (fd != -1) {
      close(fd);
    }
  }

  bool valid() const {
    return (fd != -1); 
  }

  Foo& operator=(Foo rhs) {
    rhs.swap(*this);
    return *this;
  }
  // optional: Foo& operator=(const Foo &) = delete;

  void swap(Foo &other) {
    std::swap(fd, other.fd);
  }

private:
  int fd;
};

关于c++ - 使用文件描述符移动对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56369138/

相关文章:

c++ - 为什么链接到 librt 在 g++ 和 clang 之间交换性能?

c++ - "constant"GtkLabel 的 gtk+ 信号

c++ - vector 在递归调用中使用时与数组有何不同?

c# - 如何以编程方式清除 Kerberos 票证缓存

c++ - cudaOccupancyMaxActiveBlocksPerMultiprocessor 未定义

c++ - 带有线程包装器 unique_ptr 的双端队列

c++ - 这段代码有什么错误

C++ 错误 c2679 : binary '[' : no operator found which takes a right-hand operand of type 'SalesItem' (or there is no acceptable conversion)

c++ - 如何在C++中生成高精度的随机 double ?

c++ - valgrind 和 openmp,仍然可以访问并可能丢失,这很糟糕吗?