![]() |
#2
rjsp2017-06-09 15:16
|
当unique_ptr 绑定到动态数组,析构时默认的删除其使用delete[] 来释放动态对象
当时怎么知道模板参数是一个对象还是数组呢,
下面是我实现的一个简单的Unique_ptr(不支持类似Unique_ptr<X[]> (new X[N])这样的操作, 该怎么解决这个问题, 求指教)

struct Default_deleter {//默认的删除器
public:
template<typename Element>
void operator()(Element* pe) //这里尝试使用引用的方式, void operator() (Element &e)
{ //delete (&e) (error: unknown array size in delete) 看错误提示好像知道这是个数组,但是在代码里怎么知道这是个数组呢?
delete pe;
}
};
//delete[] TODO
template<typename Element,
typename Deleter = Default_deleter> class Unique_ptr {
public:
Unique_ptr(): mPtr(nullptr) {}
Unique_ptr(Element *ptr): mPtr(ptr) {}
Unique_ptr(Element *ptr, Deleter d): mPtr(ptr), mDeleter(d) {}
Unique_ptr(const Unique_ptr&) = delete;
Unique_ptr& operator=(const Unique_ptr&) = delete;
// Unique_ptr = nullptr
Unique_ptr& operator=(void *p);
~Unique_ptr() {del();}
Element* release();
void reset(Element* p = nullptr);
Element* get();
Element& operator*();
Element* operator->();
explicit operator bool() const {return nullptr != mPtr;}
private:
Element *mPtr;
Deleter mDeleter;
void del();
};
template<typename Element, typename Deleter>
Element& Unique_ptr<Element, Deleter>::operator*()
{
assert(*this);
return *mPtr;
}
template<typename Element, typename Deleter>
Element* Unique_ptr<Element, Deleter>::operator->()
{
return &(**this);
}
template<typename Element, typename Deleter>
void Unique_ptr<Element, Deleter>::del()
{
if (*this) {
mDeleter(mPtr);
mPtr = nullptr;
}
}
template<typename Element, typename Deleter>
Element* Unique_ptr<Element, Deleter>::release()
{
auto p = mPtr;
mPtr = nullptr;
return p;
}
template<typename Element, typename Deleter>
void Unique_ptr<Element, Deleter>::reset(Element* p)
{
del();
mPtr = p;
}
public:
template<typename Element>
void operator()(Element* pe) //这里尝试使用引用的方式, void operator() (Element &e)
{ //delete (&e) (error: unknown array size in delete) 看错误提示好像知道这是个数组,但是在代码里怎么知道这是个数组呢?
delete pe;
}
};
//delete[] TODO
template<typename Element,
typename Deleter = Default_deleter> class Unique_ptr {
public:
Unique_ptr(): mPtr(nullptr) {}
Unique_ptr(Element *ptr): mPtr(ptr) {}
Unique_ptr(Element *ptr, Deleter d): mPtr(ptr), mDeleter(d) {}
Unique_ptr(const Unique_ptr&) = delete;
Unique_ptr& operator=(const Unique_ptr&) = delete;
// Unique_ptr = nullptr
Unique_ptr& operator=(void *p);
~Unique_ptr() {del();}
Element* release();
void reset(Element* p = nullptr);
Element* get();
Element& operator*();
Element* operator->();
explicit operator bool() const {return nullptr != mPtr;}
private:
Element *mPtr;
Deleter mDeleter;
void del();
};
template<typename Element, typename Deleter>
Element& Unique_ptr<Element, Deleter>::operator*()
{
assert(*this);
return *mPtr;
}
template<typename Element, typename Deleter>
Element* Unique_ptr<Element, Deleter>::operator->()
{
return &(**this);
}
template<typename Element, typename Deleter>
void Unique_ptr<Element, Deleter>::del()
{
if (*this) {
mDeleter(mPtr);
mPtr = nullptr;
}
}
template<typename Element, typename Deleter>
Element* Unique_ptr<Element, Deleter>::release()
{
auto p = mPtr;
mPtr = nullptr;
return p;
}
template<typename Element, typename Deleter>
void Unique_ptr<Element, Deleter>::reset(Element* p)
{
del();
mPtr = p;
}