clone_ptr problem, I need to create a copy object using a function of the library instead of new
I am a bit new to templates in C++ so forgive me if this question is confusing or stupid, I just have a problem where I want to implement a clone smart pointer so I don't have to create copy constructors for each and every class that uses my underlying XML library that only seems to use object pointers and not smart pointers. The problem is that my traits need to create the new objects using functions from the underlying library and I do not know how I would go about doing that in a template/traits class. I have posted all the code with some comments below, if anybody could advice, I'd appreciate it.
If something is unclear, please ask and I will try to clarify.
#ifndef CLONE_PTR_H
#define CLONE_PTR_H
#include <algorithm>
#include <functional>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
struct DOMObject_cloner
{
static DOMDocument* clone(DOMDocument* pPtr)
{
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core")); // this looks wrong, depends on DOMIMplementation_cloner being done really... how do I do this properly
return pPtr ? : impl->createDocument(...) //I need this function for a DOMDocument* to be created!!!
}
};
struct DOMImplementation_cloner
{
static DOMImplementation* clone(DOMImplementation* pPtr)
{
return pPtr ? DOMImplementationRegistry::getDOMImplementation(X("Core")) : 0;
}
};
template<typename T>
struct default_clone
{
static T* clone(T* pPtr)
{
return pPtr ? pPtr->clone() : 0;
}
};
template <typename T, typename Cloner = default_clone<T> >
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() ? Cloner()(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);
开发者_JS百科 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);
}
private:
pointer mPtr;
//default_clone Cloner;
};
template <typename T1>
bool operator!(const clone_ptr<T1>& pX)
{
return pX.get() == 0;
};
template <typename T1, typename T2>
bool operator>=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst < pSecond);
};
// compare
template <typename T1, typename T2>
bool operator==(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return pFirst.get() == pSecond.get();
};
template <typename T1, typename T2>
bool operator!=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst == pSecond);
};
template <typename T1, typename T2>
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>
bool operator<=(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return !(pFirst > pSecond);
};
template <typename T1, typename T2>
bool operator>(const clone_ptr<T1>& pFirst, const clone_ptr<T2>& pSecond)
{
return pSecond < pFirst;
};
#endif
I am not really sure if I understand your question, but I see one thing wrong with your code. DOMObject_cloner
and DOMImplementation_cloner
should be specializations of default_clone
, like this:
template<>
struct default_clone<DOMDocument> {
static DOMDocument* clone(DOMDocument* pPtr)
{
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
return pPtr ? : impl->createDocument(...);
}
};
Template specialization is the whole point of traits in C++.
精彩评论