使用RAII在给定次数的迭代后重新分配资源

Using RAII to re-allocate a resource after a given number of iterations

本文关键字:新分配 分配 资源 迭代 RAII 使用      更新时间:2023-10-16

我需要处理大量的项目。为此,需要一个资源,在这种情况下,该资源是一个外部软件程序。

由于外部软件的内存泄漏,不可能用一个资源实例处理所有项目。出于性能原因,不能选择创建资源的新实例。因此,我需要处理给定大小N的部分项目。这意味着我创建一个资源实例,处理接下来的N个项目,然后释放资源。重复此过程,直到处理完所有项目。

项目的处理实际上是一个复杂的过程,可能会导致不同类型的故障(异常(。因此,我喜欢使用RAII习惯用法来管理资源,并确保每个实例都被干净地释放。

用两个嵌套循环来实现这一点并没有什么大不了的,如本例所示:

#include <iostream>
#include <vector>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resourcen"; }
~ResourceAllocator() { std::cout << "Deallocating resourcen"; }
void Process(int n) { std::cout << "Processing item " << n << "n"; }
};
int main()
{
const int totalSize = 20;
const int portionSize = 6;
std::vector<int> items(totalSize);
int count = 0;
bool complete = false;
while (!complete) {
ResourceAllocator a;
for (int i = 0; i < portionSize; i++) {
a.Process(items[i]);
count++;
if (count >= totalSize) {
complete = true;
break;
}
}
}
}

然而,我一直在想,是否有一种解决方案只需要一个循环。

我创建一个资源实例,处理接下来的N个项目,然后取消分配资源。重复此过程,直到处理完所有项目。

您可以使用移动语义来转移资源的所有权。当遵循RAII习惯用法的对象成为移动分配的目标时,它会释放其拥有的资源(如果有的话(,并获得分配给它的资源的所有权——分配操作的来源:

Resource r(/* 1st resource */);
// ...
r = Resource(/* 2nd resource */);

分配应该释放r拥有的资源,并获得正在创建的新资源(即Resource(/* 2nd resource */)(的所有权。

您应该为类实现移动赋值运算符。处理完对象后,将使用这些对象作为移动指定的目标。

另一种选择是使用该值的容器,并每N次迭代重置一次。

#include <iostream>
#include <vector>
#include <optional>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resourcen"; }
~ResourceAllocator() { std::cout << "Deallocating resourcen"; }
void Process(int n) { std::cout << "Processing item " << n << "n"; }
};
int main()
{
const int totalSize = 20;
const int portionSize = 6;
std::vector<int> items(totalSize);
{
std::optional<ResourceAllocator> a;
for (int i = 0; i < items.size(); ++i)
{
if (i % portionSize == 0) a.emplace();
a->Process(items[i]);
}
}
}