Ray*_*yat 2 c++ opencv smart-pointers raii
我正在使用C++与OpenCV库,这是一个库图像处理,虽然这与这个问题无关.目前我有一个设计决定.
作为C库的OpenCV将其数据结构(例如CvMat)声明为结构体.要创建它们,可以使用cvCreateMat之类的函数,要释放它们,可以使用cvReleaseMat等函数.作为一名C++程序员,我创建了一个特殊的cv_scoped类,当它超出范围时会自动调用cvReleaseMat(如boost::scoped_ptr).
什么我现在意识到的是,我希望我可以使用auto_ptr,并shared_ptr在案件.我只是觉得为自己cv_auto_ptr和cv_shared_ptr类编写代码是个坏主意,更不用说浪费时间了.所以我一直在寻找解决方案,我想出了三种可能性.
首先,我可以使用我已经制作的cv_scoped类.我将它重命名为cv_ptr然后使用智能指针:std::auto_ptr<cv_ptr>.关于这个令人讨厌的事情是,我总是要两次取消引用:
std::auto_ptr<cv_ptr> matrix(cv_ptr(cvCreateMat(320, 240, CV_32FC3)));
cvPow(matrix.get()->get()); // one get for the auto_ptr, one for the cv_ptr
Run Code Online (Sandbox Code Playgroud)
我知道看起来我可以声明一个隐式转换,但实际上我无法实现 - 大多数OpenCV的函数都有参数void* - 因此不会调用隐式转换.我真的想要一种这样做的方式,我不必进行双重引用.
其次,我可以以某种方式覆盖operator delete.我不想覆盖全局运算符delete,因为我只想将它应用于CvMat(和其他一些)类型.但是,我无法更改库,因此无法添加operator delete到CvMat结构中.所以我不知道这是怎么回事.
第三,我可以只重写我自己auto_ptr,scoped_ptr和shared_ptr.他们不是大班,所以不会太难,但我觉得这是糟糕的设计.如果我这样做,我可能会做这样的事情:
class cv_auto_ptr {
public:
cv_auto_ptr();
~cv_auto_ptr();
// each method would just be a proxy for the smart pointer
CvMat* get() { return this->matrix_.get()->get(); }
// all the other operators/methods in auto_ptr would be the same, you get the idea
private:
auto_ptr<cv_ptr> matrix_; // cv_ptr deletes CvMat properly
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下你会做什么?请帮我解决这个问题.
您可以考虑的一种方法是使用std::tr1::shared_ptr具有提供自定义删除功能的事实.我对OpenCV不熟悉,所以我推断你写的是什么.
struct CvMatDeleter
{
void operator( CvMat* p ) { cvReleaseMat( p ) ; }
};
void test()
{
std::tr1::shared_ptr< CvMat > pMat( cvCreateMat(320, 240, CV_32FC3), CvMatDeleter() );
// . . .
}
Run Code Online (Sandbox Code Playgroud)
因为删除器存储在共享指针中,所以您可以正常使用它,并且当最终需要删除共享原始指针时,cvReleaseMat将根据需要调用它.请注意,auto_ptr并且scoped_ptr是更轻的类,因此没有自定义删除器的功能,但如果您已经为较小的开销做好了准备,那么shared_ptr可以在他们的位置使用.