具有POSIX文件描述符对象的C 复制构造函数
C++ Copy constructor of object owning a POSIX file descriptor
我需要将拥有POSIX文件描述符的C 对象放在向量中。我有一个用来创建对象的filepath的向量。这是我的代码:
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;
}
在MightyObject中,我的对象有错误的文件描述符...
我在做什么错?
所示的代码应包含正确的文件描述符,尽管它会将描述符泄漏到分配中。要修复它,您应该将其更改为:
- 修复分配运算符中的泄漏;
- 处理自我分配;
- 实现A 移动构造函数以优化移动(并且因为此类是移动构造的好处的教科书示例);
- 处理错误。
例如(未经测试):
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;
}
一旦了解了移动语义,就可以通过部署副本和交换成语来减少操作员之间的代码重复。
请注意,以上应理解为一种编码和理解练习。在生产中,您可能不想在复制对象时分配新的文件描述符。更好的设计将使文件只移动,并将MightyObject
作为std::shared_ptr<Handle>
实现。这将完全避免使用dup
并摆弄复制构造函数,分配运算符等,因为所有这些都将由shared_ptr
处理。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用