2014-03-04 11 views
5

我想要将open/close POSIX API包装为一个RAII兼容对象,如std::unique_ptr。但open函数返回int(即不是HANDLE,这是一个指向void的指针),我不确定如何使用std::unique_ptr模板类与int。有人能帮帮我吗?如何使用std :: unique_ptr <T>以及返回int的接口?

+0

你为什么要这么做?如果你没有指向空闲的指针,'shared_ptr'是没有用的。 –

+2

由于返回的值不是指针,因此共享指针不适用于此类。阅读[向标准库添加其他RAII包装的建议](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3677.html)。 – RedX

+1

@FilipeGonçalves因为它很聪明,并且允许您在没有人需要时自动关闭文件而不会泄漏资源? – RedX

回答

2

真的,所有你想要的是关闭(int fileHandle)为你管理,对吧?为什么不用一个为你调用close()的析构函数创建一个简单的C++类?我认为这是你正在寻找的行为。

std :: shared_ptr,朋友只处理用new创建的堆指针,并且会调用delete ptr,而不是你在这里寻找的东西。

编辑:费尔南德斯先生说得很好。 shared_ptr <>为你管理引用计数,因此如果使用它与自定义的删除器来处理来自c库调用(例如文件句柄)的不透明句柄,这是一件非常合理的事情,只要其他团队成员遵循一点点棘手。它也直接回答OP的问题。

这是关于Herb Sutter网站的主题的interesting discussion

+0

请记住,如果文件无法打开,则不应尝试在析构函数中关闭它。 – RedX

+0

@Steger问题是我想复制(-construct)类对象。 –

+1

@EgorTensin对于复制,您可以在对象内部保留一个lockCount,成功打开()后将其设置为1,在每个副本上递增并在dtor中递减。当它变为零时,调用close()。这是它完成的标准方式。除非你想为每个副本打开一个新的文件句柄,否则你不需要lockCount。哦,是的,文件句柄和锁定计数必须位于一个新的单独对象中,因此它可以在多个PosixFileHandle对象中共享。我的程序中有几个地方有这种模式。让我知道如果这不明确。 – Steger

1

它不能保证按标准工作(结果是实现定义的),但我猜想在大多数理智的实现中,执行int -> void* -> int的往返运算会得到相同的int值。所以,你可以这样做:

std::shared_ptr<void> raii(
    reinterpret_cast<void*>(open(/*...*/), 
    [](void *p) { close(reinterpret_cast<int>(p)); } 
); 

它使用它调用close()一个定制删除。您可能希望在自己的课程中包装这些内容,以提供更好的外部界面,同时仍然利用std::shared_ptr的实现方式来共享线程安全性。

+0

*全局指针*的布局是不透明的,但可以在一个整数之间进行转换。 (N1548§6.3.2.3¶5,¶6)(N3242§5.2.10¶4,¶5;§3.7.4.3¶1,¶3) 明确提供了适当的转换类型的整数类型,但可选。 (N1548§7.20.1.4) –

+0

因此,'#ifdef INTPTR_MAX'用'intptr_t'开关'int'。 '#ifndef INTPTR_MAX #error“这个环境是不完善的:-(”'。 –

+1

@CharlesLWilcox你需要使用'intptr_t'来安全地将一个'void *'转换为一个整数并返回。 ,映射只是实现定义的(5.2.10p5)。 – Angew

相关问题