在给定的迭代次数后使用 RAII 重新分配资源
Using RAII to re-allocate a resource after a given number of iterations
我需要处理大量项目。为此,需要一个资源,在本例中是一个外部软件程序。
由于外部软件的内存泄漏,无法使用单个资源实例处理所有项目。出于性能原因,创建资源的新实例不是一个选项。因此,我需要处理给定大小 N 的部分项目。这意味着我创建资源实例,处理接下来的 N 个项目,然后释放资源。重复此过程,直到处理完所有项目。
物品的处理实际上是一个复杂的过程,可能会导致不同类型的故障(异常)。因此我喜欢使用 RAII 习惯用法来管理资源并确保每个实例都被干净地释放。
用两个嵌套循环实现这个没什么大不了的,如本例所示:
#include <iostream>
#include <vector>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resource\n"; }
~ResourceAllocator() { std::cout << "Deallocating resource\n"; }
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;
}
}
}
}
但是我一直想知道是否有只需要一个循环的解决方案。
I create an instance of the resource, process the next N items, then deallocate the resource. This process is repeated until all items have been processed.
您可以使用移动语义 来转移资源的所有权。当遵循 RAII 习语的对象是移动分配的目标时,它会释放它拥有的资源(如果有的话)并取得分配给它的资源的所有权——分配操作的来源:
Resource r(/* 1st resource */);
// ...
r = Resource(/* 2nd resource */);
分配应释放 r
拥有的资源并获得正在创建的新资源的所有权(即 Resource(/* 2nd resource */)
)。
您应该为您的 class 实施 move assignment operator。当对象被处理后,你使用这些对象作为移动分配的目标。
另一种方法是为值使用一个容器,并在每 N 次迭代后重置它。
#include <iostream>
#include <vector>
#include <optional>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resource\n"; }
~ResourceAllocator() { std::cout << "Deallocating resource\n"; }
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]);
}
}
}
我需要处理大量项目。为此,需要一个资源,在本例中是一个外部软件程序。
由于外部软件的内存泄漏,无法使用单个资源实例处理所有项目。出于性能原因,创建资源的新实例不是一个选项。因此,我需要处理给定大小 N 的部分项目。这意味着我创建资源实例,处理接下来的 N 个项目,然后释放资源。重复此过程,直到处理完所有项目。
物品的处理实际上是一个复杂的过程,可能会导致不同类型的故障(异常)。因此我喜欢使用 RAII 习惯用法来管理资源并确保每个实例都被干净地释放。
用两个嵌套循环实现这个没什么大不了的,如本例所示:
#include <iostream>
#include <vector>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resource\n"; }
~ResourceAllocator() { std::cout << "Deallocating resource\n"; }
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;
}
}
}
}
但是我一直想知道是否有只需要一个循环的解决方案。
I create an instance of the resource, process the next N items, then deallocate the resource. This process is repeated until all items have been processed.
您可以使用移动语义 来转移资源的所有权。当遵循 RAII 习语的对象是移动分配的目标时,它会释放它拥有的资源(如果有的话)并取得分配给它的资源的所有权——分配操作的来源:
Resource r(/* 1st resource */);
// ...
r = Resource(/* 2nd resource */);
分配应释放 r
拥有的资源并获得正在创建的新资源的所有权(即 Resource(/* 2nd resource */)
)。
您应该为您的 class 实施 move assignment operator。当对象被处理后,你使用这些对象作为移动分配的目标。
另一种方法是为值使用一个容器,并在每 N 次迭代后重置它。
#include <iostream>
#include <vector>
#include <optional>
class ResourceAllocator {
public:
ResourceAllocator() { std::cout << "Allocating resource\n"; }
~ResourceAllocator() { std::cout << "Deallocating resource\n"; }
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]);
}
}
}