我已阅读DDJ中有关范围警卫(Generic: Change the Way You Write Exception-Safe Code — Forever)的文章,并了解他们的常见用法。动态创建范围警卫
然而,常见的用途是实例化堆栈上的特定堆栈后卫特定的操作,例如:
{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed
,但如果我要安排清理操作在运行时,例如什么当我有一个循环:
{
vector<FILE*> topSecretFiles;
for (int i=0; i<numberOfFiles; ++i)
{
char filename[256];
sprintf(filename, "cia%d.txt", i);
FILE* topSecret = fopen(filename);
topSecretFiles.push_back(topSecret);
ON_BLOCK_EXIT(std::fclose, topSecret); // no good
}
}
显然,上述例子是行不通的,因为topSecret
将与沿着范围被关闭。我想要一个范围守卫模式,我可以轻松地排队清理操作,我确定需要在运行时。有没有这样的东西可用?
我不能将范围守护对象放到标准队列中,导致原始对象(我推送的对象)在流程中被解散。如何推送堆分配的堆栈守卫,并使用一个队列删除其在dtor上的成员?有没有人有更聪明的做法?
是的,对于资源析构函数(如文件句柄)来说,RAII是最好的。我只使用范围守卫来表达那些难以表现为“资源”的事物,例如 report(OperationStart); ON_BLOCK_EXIT(report,OperationEnd); doSomething(); – Ilya 2009-10-14 12:05:03
遗憾的是,我的编译器中没有TR1,所以我无法使用shared_ptr。然而,auto_ptr的向量/队列可能正常工作(假设我是堆 - 分配我的范围守卫并将它们推送到向量/队列中)。我很想知道一些C++类将变得“可移动”(不知道这个术语)。这是用refcounts完成的吗?也许我应该让范围警卫“可移动”呢? –
Ilya
2009-10-14 12:06:13
auto_ptr <...>的vector/queue显然不是一个好主意,因为auto_ptrs不可复制! – 2009-10-14 12:58:19