有条件地使用 RAII 的最佳方法
我有一个很好的资源管理课程。具体来说,让它成为一个用于管理 FILE* 的 File 类(处理打开和关闭操作)
当资源不需要由我管理并且由其他人负责的情况下,通常的方法是什么?
出于说明目的,我目前有这样的东西:
int main(int argc, char** argv)
{
File my_file(argv[1]); //I unconditionaly obtain the resource
//...
return 0; //and unconditionally relinquish with the destructor
}
并且想要类似的东西
int main()
{
if(argc <= 1){
//use stdin that is already available
}else{
//obtain a file from argv[1]
}
//...
if(argc <= 1){
//nothing to do
}else{
//close the file we obtained
}
}
(但不那么丑陋,更强大,等等......)
I have a nice resource managing class. For concreteness, lets have it be a File class for managing a FILE* (handling the open and close operations)
What is the usual approach when there are cases where the resource doesn't need to be managed by me, and is someone else's responsibility?
For ilustrative purposes, I currently have something like this:
int main(int argc, char** argv)
{
File my_file(argv[1]); //I unconditionaly obtain the resource
//...
return 0; //and unconditionally relinquish with the destructor
}
And want something like
int main()
{
if(argc <= 1){
//use stdin that is already available
}else{
//obtain a file from argv[1]
}
//...
if(argc <= 1){
//nothing to do
}else{
//close the file we obtained
}
}
(but less ugly, more robust, etc...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
boost::shared_ptr
允许您传入自定义析构函数。如果您要包装外部管理的指针,则可以传递无操作:现在,当您需要真正的 RAII 对象时,请使用普通的
boost::shared_ptr
,当您需要假的时,使用这样的适配器 - 它的作用与普通指针完全相同。boost::shared_ptr
allows you to pass in a custom destructor. If you're wrapping an externally-managed pointer, you can pass a no-op:Now when you need a true RAII object, use a normal
boost::shared_ptr
, and when you need a fake one, use an adapter like this - it'll act exactly like a normal pointer.您的 RAII 类已经保留了足够的状态来知道何时销毁它所控制的资源。它还可以包含一个标志,告诉它资源是否应该被销毁,或者您可以在计数器上使用特殊值来指示资源是在类外部控制的。
那么你所需要的就是在获取资源时控制状态的方法。例如,您可以有两个不同的构造函数,或者构造函数上的参数具有默认值。您可以使用
Attach
方法来附加现有资源。这完全取决于你。Your RAII class is already keeping enough state to know when to destroy the resource it is controlling. It can also contain a flag that tells it if the resource should be destroyed, or you can use a special value on the counter to indicate that the resource is controlled outside the class.
Then all you need is a way to control the state when you obtain the resource. You can have two different constructors for example, or a parameter on the constructor with a default value. You could have an
Attach
method that attaches an existing resource. It's entirely up to you.您可以将是否使用资源的逻辑推送到资源管理类中。那么就不再是有条件的了。只要做
You can push the logic of whether or not to use the resource inside your resource managing class. Then it isn't conditional anymore. Just do
大多数常见模式不允许这样做。但是,您可以允许自定义分配器插件(标准为其容器提供了这些插件),这将允许这些语义。这是一个简短的示例 -
Most common patterns do not allow for this. However, you can allow custom allocator plugins, which the Standard has for it's containers, that will allow for these semantics. This is a brief sample-