проблема clone_ptr, мне нужно создать объект копирования, используя функцию библиотеки вместо новой - PullRequest
1 голос
/ 02 ноября 2010

Я немного новичок в шаблонах в C ++, так что простите, если этот вопрос сбивает с толку или глуп, у меня просто проблема, когда я хочу реализовать интеллектуальный указатель клонирования, поэтому мне не нужно создавать конструкторы копирования для каждого икаждый класс, который использует мою базовую библиотеку XML, которая, кажется, использует только указатели объектов, а не умные указатели.Проблема в том, что мои черты должны создавать новые объекты с использованием функций из базовой библиотеки, и я не знаю, как бы я поступил в классе template / traits.Я разместил весь код с некоторыми комментариями ниже, если кто-нибудь может посоветовать, я был бы признателен.

Если что-то неясно, пожалуйста, спросите, и я постараюсь уточнить.

#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);
            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

1 Ответ

1 голос
/ 02 ноября 2010

Я не совсем уверен, что понимаю ваш вопрос, но я вижу одну ошибку в вашем коде.DOMObject_cloner и DOMImplementation_cloner должны быть специализациями default_clone, например:

template<>
struct default_clone<DOMDocument> {
    static DOMDocument* clone(DOMDocument* pPtr)
    {
        DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
        return pPtr ?  : impl->createDocument(...);
    }
};

Специализация шаблонов - это весь смысл черт в C ++.

...