C++ 用自定义删除程序封装C类型指针的常用方法

C++ 用自定义删除程序封装C类型指针的常用方法,c++,c,shared-ptr,C++,C,Shared Ptr,几乎所有C库中的C类型对象都有一些自定义的删除程序,例如OpenCV中的IplImage*具有cvReleaseImage(IplImage**)deleter函数。在C++中,我希望我的代码能够始终确保每个对象最终被删除。 我想以某种方式使用std::shared_ptr及其自定义删除功能是最有意义的 一个示例/可能的解决方案是,我只使用shared\u ptr,但使用专门版本的default\u delete。但是,请参阅关于这些缺点的答案:它不能被C++标准保证,StRADYPPTR 将使

几乎所有C库中的C类型对象都有一些自定义的删除程序,例如OpenCV中的
IplImage*
具有
cvReleaseImage(IplImage**)
deleter函数。在C++中,我希望我的代码能够始终确保每个对象最终被删除。 我想以某种方式使用
std::shared_ptr
及其自定义删除功能是最有意义的

一个示例/可能的解决方案是,我只使用
shared\u ptr
,但使用专门版本的
default\u delete
。但是,请参阅关于这些缺点的答案:它不能被C++标准保证,StRADYPPTR <代码>将使用<代码> Debug Type > /Cuff>作为默认的删除器,并且我不允许专精<代码> Debug Type < /C> >(我想)。 另一个解决方案是这样的:

shared_ptr<IplImage> makeIplImage(IplImage* ptr) {
    return shared_ptr<IplImage>(ptr, default_delete<IplImage>()); // using my specialised default_delete
}

我真的没有在野外看到这么多这样的解决方案。使用它们是个坏主意吗?如果是这样,那么我想我错过了什么,但是什么呢?或者最常见/最有意义的方法是什么?

包装器似乎是一种好方法。如果为C++类定义析构函数,那么它可以为您释放内存。当您的类超出范围时,会自动调用析构函数,因此这应该会让您了解您想要了解的内容。如果在内存清理过程中有用的话,还可以在析构函数中实现对
NUL
ptr或悬空ptr的检查

class IplImageObj {
    IplImage* ptr;
    ~IplImageObj(){ /* The destructor: you can call cvReleaseImage from here  */}
public:
    IplImageObj(IplImage* img): ptr(img){}
    // ...
};
在上面的代码段中,数据成员
ptr
是私有的,因此您可能需要访问器函数来处理它


我的C++讲师强烈反对<代码>公共< /Cord>在<代码>类< /代码>中的数据成员声明。如果您想将数据成员公开,那么

struct
具有当今
class
的所有功能,并且人们对数据成员的公开访问更加宽容

我不知道什么是最常见的,但我想说的是用包装纸。因为如果您需要封装分配/删除,那么可能还需要封装其他内容。将整个C库的使用情况封装在这样一个类中可能是明智的。您可以相当容易地适应
boost::intrusive\u ptr
,或者您应该编写自己的smart\u ptr。我倾向于编写ptr处理程序,因为所有标准或boost实现都缺乏特性。我在它们身上看到的最大缺陷是,不能将处理类与它所持有的指针关联起来,以检测挂起的引用。@Raxvan:谢谢你的建议。我认为,
instrusive\u ptr
只有在已经有一些重新计算的情况下才有意义,但在大多数情况下(对于
IplImage
),没有。关于关联:在关于
shared\u ptr
的Boost文档中,他们建议在这种情况下使用
weak\u ptr
(如果我理解正确的话)。
class IplImageObj {
    IplImage* ptr;
    ~IplImageObj(){ /* The destructor: you can call cvReleaseImage from here  */}
public:
    IplImageObj(IplImage* img): ptr(img){}
    // ...
};