gpt4 book ai didi

拥有 POSIX 文件描述符的对象的 C++ 复制构造函数

转载 作者:IT王子 更新时间:2023-10-29 01:04:58 26 4
gpt4 key购买 nike

我需要将拥有 POSIX 文件描述符的 C++ 对象放入 vector 中。我有一个文件路径 vector ,我用它来创建我的对象。这是我的代码:

main.cpp

std::vector<MightyObject> mightyObjects;
std::vector<const char*> paths = {"awesomePath1", "awesomePath2"};
for (std::vector<const char*>::iterator it = paths.begin(); it != paths.end(); ++it)
{
mightyObjects.emplace_back(MightyObject(*it));
}

MightyObject.cpp

MightyObject::MightyObject(const char* path)
{
this->fd = open(path, O_RDWR | O_NONBLOCK);
}

MightyObject::~MightyObject()
{
close(this.fd);
}

MightyObject::MightyObject(const MightyObject& obj)
{
this->fd = dup(obj.fd);
}

MightyObject& MightyObject::operator=(const MightyObject& other)
{
this->fd = dup(other.fd);
return *this;
}

在 mightyObjects 中,我有带有错误文件描述符的对象...

我做错了什么?

最佳答案

所示代码应包含正确的文件描述符,尽管它会在分配时泄漏描述符。要修复它,您应该将其更改为:

  • 修复赋值运算符中的漏洞;
  • 处理自分配;
  • 实现移动构造函数以优化移动(并且因为此类是移动构造好处的教科书示例);
  • 处理错误。

例如(未经测试):

static int safe_dup(int fd) {
int copy = dup(fd);
if (copy < 0)
throw std::runtime_error(strerror(errno));
return copy;
}

MightyObject::MightyObject(const char* path) {
this->fd = open(path, O_RDWR | O_NONBLOCK);
if (this->fd == -1)
throw std::runtime_error(strerror(errno));
}

MightyObject::~MightyObject() {
if (this->fd != -1)
close(this->fd);
}

MightyObject::MightyObject(const MightyObject& other) {
this->fd = safe_dup(other.fd);
}

MightyObject& MightyObject::operator=(const MightyObject& other) {
if (this != &other) {
close(this->fd);
this->fd = safe_dup(other.fd);
}
return *this;
}

MightyObject::MightyObject(MightyObject&& other) {
// "move" file descriptor from OTHER to this: no duping is needed,
// we just take the descriptor and set the one in OTHER to -1, so
// it doesn't get closed by OTHER's destructor.
this->fd = other.fd;
other.fd = -1;
}

MightyObject& MightyObject::operator=(MightyObject&& other) {
// move assignment operator
close(this->fd);
this->fd = other.fd;
other.fd = -1;
}

一旦理解了移动语义,就可以通过部署 copy and swap idiom 来减少运算符之间的代码重复。 .

请注意,以上内容应理解为编码和理解练习。在生产中,您可能不希望在复制对象时分配新的文件描述符。更好的设计会使文件句柄只移动并实现 MightyObject作为std::shared_ptr<Handle> .这将完全避免 dup并摆弄复制构造函数、赋值运算符等,因为所有这些都将由 shared_ptr 处理.

关于拥有 POSIX 文件描述符的对象的 C++ 复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41104320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com