我正在尝试编写DriverIterator类来遍历计算机中的所有卷。
我了解下一类可能会导致内存泄漏,因为:
current_ = std::make_unique<Driver>(paths);
可能会引发异常(由于某种原因。),因此构造将无法完成,结果析构函数将不会被调用,并且句柄将无法正确关闭。
当我取消设计时,一旦收到手柄,就应该停止构造。但是我该如何实现呢?FindFirstVolumeW还为我提供了在构造函数完成之前需要使用的数据。
DriverIterator.hpp:
class DriverIterator final
{
public:
explicit DriverIterator();
~DriverIterator();
private:
std::unique_ptr<Driver> current_;
bool is_empty_;
HANDLE handle_;
public:
bool is_empty() const;
Driver get_current() const;
void next();
private:
HANDLE start_find();
public:
DriverIterator(const DriverIterator&) = delete;
DriverIterator(DriverIterator&&) = delete;
DriverIterator& operator=(const DriverIterator&) = delete;
DriverIterator& operator=(DriverIterator&&) = delete;
};
DriverIterator.cpp:
DriverIterator::DriverIterator():
handle_(start_find())
{}
DriverIterator::~DriverIterator()
{
try
{
FindVolumeClose(handle_);
}
catch (...)
{
}
}
HANDLE DriverIterator::start_find()
{
static constexpr uint32_t MAX_BUFFER_SIZE = 1024;
wchar_t buffer[MAX_BUFFER_SIZE];
HANDLE handle = FindFirstVolumeW(buffer, MAX_BUFFER_SIZE);
if (handle == INVALID_HANDLE_VALUE)
{
//throw exception
}
wchar_t paths[1024];
DWORD res_size;
if (!GetVolumePathNamesForVolumeNameW(buffer, paths, 1024, &res_size))
{
//throw exception
}
current_ = std::make_unique<Driver>(paths);
is_empty_ = false;
return handle;
}
bool DriverIterator::is_empty() const
{
return is_empty_;
}
Driver DriverIterator::get_current() const
{
if (is_empty_)
{
//throw exception
}
return *current_;
}
void DriverIterator::next()
{
//code...
}
好,所以我创建了一个内部类'FindVolumeHandle来包装手柄。
[如果从构造函数生成异常,则不调用对象析构函数,但是将调用已构造成员的析构函数,并释放为该对象分配的内存。