我有一个clone_ptr的以下实现,试图制作需要在类中复制的对象指针的安全副本,因此我建议使用智能指针并创建克隆指针而不是使用复制构造函数。
Clone_ptr实施:
#include <algorithm>
#include <functional>
#include <xercesc/dom/DOM.hpp>
struct DOMImplementation_cloner
{
template <typename T>
T* operator()(T* pPtr) const
{
/* your clone code*/.
T = DOMImplementationRegistry::getDOMImplementation(X("Core"));
}
};
struct default_clone
{
template <typename T>
T* operator()(T* pPtr) const
{
return pPtr->clone();
}
};
template <typename T, typename Cloner = default_clone>
class clone_ptr
{
public:
// types
typedef T element_type;
typedef element_type value_type;
typedef const element_type const_value_type;
typedef value_type* pointer;
typedef const_value_type* const_pointer;
typedef value_type& reference;
typedef const_value_type& const_reference;
// creation
clone_ptr() :
mPtr(0)
{}
explicit clone_ptr(pointer pPtr) :
mPtr(pPtr)
{}
clone_ptr(const clone_ptr& pOther) :
mPtr(pOther.get() ? mCloner(pOther.get()) : 0)
{}
/* clone_ptr(const clone_ptr& pOther) :
mPtr(pOther.get() ? pOther->clone() : 0),
{}*/
clone_ptr& operator=(clone_ptr pOther)
{
swap(*this, pOther);
return *this;
}
~clone_ptr()
{
delete get();
}
// observers
pointer get() const
{
return mPtr;
}
pointer operator->() const
{
return get();
}
reference operator*() const
{
assert(get() != 0);
return *get();
}
// modifiers
pointer release()
{
pointer result = mPtr;
mPtr = 0;
return result;
}
void reset(pointer pPtr = 0)
{
*this = clone_ptr(pPtr);
}
// utility
friend void swap(clone_ptr& pFirst, clone_ptr& pSecond)
{
std::swap(pFirst.mPtr, pSecond.mPtr);
}
/////////////////////
// compare
template <typename T1, typename T2>
friend bool operator==(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return pFirst.get() == pSecond.get();
}
template <typename T1, typename T2>
friend bool operator!=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst == pSecond);
}
template <typename T1, typename T2>
friend bool operator<(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return std::less<void*>()(pFirst.get(), pSecond.get());
}
template <typename T1, typename T2>
friend bool operator<=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst > pSecond);
}
template <typename T1, typename T2>
friend bool operator>(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return pSecond < pFirst;
}
template <typename T1, typename T2>
friend bool operator>=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst < pSecond);
}
template <typename T1>
friend bool operator!(const clone_ptr<T1>& pX)
{
return pX.get() == 0;
}
private:
pointer mPtr;
default_clone mCloner;
};
///使用xerces指针,以便可以安全地复制/克隆
private class member:
clone_ptr<DOMImplementation, DOMImplementation_cloner> impl;
//compiler error:
error C2039: 'clone' : is not a member of 'xercesc_3_1::DOMImplementation'
我不明白为什么它没有使用DOMImplementation_cloner
并尝试使用default_clone?
有人可以澄清我做错了吗?
答案 0 :(得分:2)
克隆人的类型硬编码为default_clone
,而不是使用模板参数Cloner
(请参阅类定义的最后一行)。
修改为了确保您理解,您对mCloner
的定义应如下所示:
Cloner mCloner;
这样克隆人实际上就是模板参数给出的类型。
还有一件事。如果您希望在更一般的设置中使用clone_ptr
(例如,通过其他项目的同事),则应该将克隆者的类型设为T
类型的属性。这可以使用类型特征来完成(this answer给出一个例子)。这可能在您的clone_ptr
:
template< typename T, typename Cloner = cloner_traits< T >::cloner_type >
class clone_ptr {
// ...
};
这与您当前的实现具有相同的默认行为。优点是需要特殊克隆的类只会专门化cloner_traits
模板,而类的用户不必担心选择合适的克隆程序。如果您仍想覆盖任何类的克隆者,您仍然可以手动传递克隆程序。
答案 1 :(得分:2)
我建议在以下链接中使用clone_ptr类: http://www.codeproject.com/KB/stl/clone_ptr.aspx
上述类型的克隆指针不需要具有克隆功能。 与上述类型的实现相比,这种类型的克隆指针类还有其他优点。
有关详细信息,请参阅文章。