我需要让C++对象在向量中拥有POSIX文件描述符.我有一个文件路径的向量,我用它来创建我的对象.这是我的代码:
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));
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
在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;
}
Run Code Online (Sandbox Code Playgroud)
一旦理解了移动语义,就可以通过部署复制和交换习惯来减少运算符之间的代码重复.
请注意,上述内容应理解为编码和理解练习.在生产中,您可能不希望在复制对象时分配新的文件描述符.更好的设计会使文件句柄只移动并实现MightyObject为std::shared_ptr<Handle>.这将完全避免dup和摆弄复制构造函数,赋值运算符等,因为所有这些都将由处理shared_ptr.
| 归档时间: |
|
| 查看次数: |
591 次 |
| 最近记录: |