只想对设计问题提出意见.如果你有一个C++类而不是拥有其他对象,你会使用智能指针来实现吗?
class Example {
public:
// ...
private:
boost::scoped_ptr<Owned> data;
};
Run Code Online (Sandbox Code Playgroud)
"拥有"对象不能按值存储,因为它可能会在对象的生命周期内发生变化.
我的观点是,一方面,你明确表示对象是拥有的并确保删除它,但另一方面,你可以很容易地只有一个常规指针并在析构函数中删除它.这有点矫枉过正吗?
跟进:只是想感谢您的所有答案.感谢关于auto_ptr的抬头在复制整个对象时使用NULL指针留下另一个对象,我已经广泛使用了auto_ptr但是还没想到.除非我有充分的理由,否则基本上我的所有类都是boost :: noncopyable,所以没有什么可担心的.还要感谢有关异常中内存泄漏的信息,这也是很好的.我尽量不编写可能导致构造函数中的异常的东西 - 有更好的方法可以做到这一点 - 所以这应该不是问题.
我只是有另一个问题.当我问这个问题时,我想知道是否有人真的这样做了,你们似乎都提到理论上这是一个好主意,但没有人说他们真的这样做了.这让我感到惊讶!当然,一个拥有指向另一个对象的对象并不是一个新想法,我希望你们在某个时刻之前都会做到这一点.这是怎么回事?
我正在使用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(); …
Run Code Online (Sandbox Code Playgroud)