我正在使用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
.关于这个令人讨厌的事情是,我总是要两次取消引用:
std::auto_ptrmatrix(cv_ptr(cvCreateMat(320, 240, CV_32FC3))); cvPow(matrix.get()->get()); // one get for the auto_ptr, one for the cv_ptr
我知道看起来我可以声明一个隐式转换,但实际上我无法实现 - 大多数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_ptrmatrix_; // cv_ptr deletes CvMat properly }
在我的情况下你会做什么?请帮我解决这个问题.
您可以考虑的一种方法是使用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() ); // . . . }
因为删除器存储在共享指针中,所以您可以正常使用它,并且当最终需要删除共享原始指针时,cvReleaseMat
将根据需要调用它.请注意,auto_ptr
并且scoped_ptr
是更轻的类,因此没有自定义删除器的功能,但如果您已经为较小的开销做好了准备,那么shared_ptr
可以在他们的位置使用.