template <typename T>
class shared_ptr {
public:
shared_ptr(): p(nullptr), use(new std::size_t(1)) { }
explicit shared_ptr(T *pt): p(pt), use(new std::size_t(1)) { }
shared_ptr(const shared_ptr &sp): p(sp.p), use(sp.use) { if (use) ++*use; }
shared_ptr& operator=(const shared_ptr&);
~shared_ptr();
T& operator*() { return *p; }
const T& operator*() const { return *p; }
private:
T *p;
std::size_t *use;
};
template <typename T>
shared_ptr<T>::~shared_ptr() {
if (use && 0 == --*use) {
delete p; // del ? del(p) : delete p;
delete use;
}
}
如上所示。是C++ Primer 第五版16.1.6节的一个问题,请问我应该给shared_ptr类增加一个什么类型的成员del,才能够使得这个类可以接受一个可调用对象,此对象的目的是清理动态内存分配的指针,但是可以自定义这个对象的行为。
谢谢!
迷茫2017-04-17 13:21:44
可以參考一下。 。 。
template <typename Tp>
class AutoCleanHelperBase
{
public:
AutoCleanHelperBase(Tp* ptr)
:m_ptr(ptr)
{ }
virtual void destroy()
{}
protected:
Tp* m_ptr;
};
template <typename Tp, typename Deleter>
class AutoCleanHelper;
template <typename Tp>
class AutoCleanHelper<Tp, void> : public AutoCleanHelperBase<Tp>
{
public:
AutoCleanHelper(Tp* ptr)
:AutoCleanHelperBase<Tp>(ptr)
{ }
void destroy()
{
delete this->m_ptr;
}
};
template <typename Tp, typename Deleter>
class AutoCleanHelper: public AutoCleanHelperBase<Tp>
{
public:
AutoCleanHelper(Tp* ptr, Deleter del)
:AutoCleanHelperBase<Tp>(ptr)
,m_del(del)
{ }
void destroy()
{
(this->m_ptr->*m_del)();
}
private:
Deleter m_del;
};
template <typename Tp>
class AutoClean
{
public:
template <typename Tp1>
AutoClean(Tp1* ptr)
:m_helper(new AutoCleanHelper<Tp1, void>(ptr))
{}
template <typename Tp1, typename Deleter>
AutoClean(Tp1* ptr, Deleter deleter)
:m_helper(new AutoCleanHelper<Tp1, Deleter>(ptr, deleter))
{}
~AutoClean()
{
m_helper->destroy();
delete m_helper;
}
private:
AutoCleanHelperBase<Tp>* m_helper;
};
class CanDestroy
{
public:
~ CanDestroy()
{
std::cout <<"I'm destroy now !!!\n";
}
};
class ExplicitDestroy
{
public:
void destroy()
{
std::cout <<"I'm also destroy now !!!\n";
}
};
int main()
{
AutoClean<CanDestroy> clean1(new CanDestroy);
AutoClean<ExplicitDestroy> clean2(new ExplicitDestroy, &ExplicitDestroy::destroy);
return 0;
}
PHP中文网2017-04-17 13:21:44
可在shared_ptr裡維護一個類型為void (*)(T*)的函數指針,然後在需要釋放記憶體的時候調一下這個函數。一個簡單的例子:
void release(somePointer* ptr) {
delete ptr;
ptr = nullptr;
}
我太天真了=,-,你可以看看這個答案 關於c++中,shared_ptr中的刪除器
大家讲道理2017-04-17 13:21:44
參考了araraloren的回答,感謝!
template <typename T>
class Contents {
public:
Contents(T* pt): contents(pt) { }
virtual void destory() { }
protected:
T* contents;
};
template <typename T, typename D>
class ContentsWithDeleter;
template <typename T>
class ContentsWithDeleter<T, void> : public Contents<T> {
public:
ContentsWithDeleter(T *pt): Contents<T>(pt) { }
void destory() override { delete this->contents; }
};
template <typename T, typename D>
class ContentsWithDeleter : public Contents<T> {
public:
ContentsWithDeleter(T *pt, D del): Contents<T>(pt), deleter(del) { }
void destory() override { deleter(this->contents); }
private:
D deleter;
};
template <typename T>
class shared_ptr { // todo
public:
template <typename Tp>
shared_ptr(Tp *ptr): p(new ContentsWithDeleter<Tp, void>(ptr)), use(new std::size_t(1)) { }
template <typename Tp, typename D>
shared_ptr(Tp *ptr, D del): p(new ContentsWithDeleter<Tp, D>(ptr, del)), use(new std::size_t(1)) { }
shared_ptr(const shared_ptr &sp): p(sp.p), use(sp.use) { if (use) ++*use; }
shared_ptr& operator=(const shared_ptr&);
~shared_ptr();
T& operator*() { return *p; }
const T& operator*() const { return *p; }
private:
Contents<T> *p;
std::size_t *use;
};
template <typename T>
shared_ptr<T>::~shared_ptr() {
if (use && 0 == --*use) {
p->destory(); // del ? del(p) : delete p;
delete p;
delete use;
}
}
template <typename T>
shared_ptr<T>& shared_ptr<T>::operator=(const shared_ptr<T> &rhs) {
if (rhs.use) ++*rhs.use;
if (use && 0 == --*use) {
p->destory();
delete p;
delete use;
}
p = rhs.p;
use = rhs.use;
return *this;
}