代码之家  ›  专栏  ›  技术社区  ›  Tony The Lion

克隆执行错误

  •  1
  • Tony The Lion  · 技术社区  · 14 年前

    为了安全复制需要在类中复制的对象指针,我使用了克隆指针的以下实现,因此建议我使用智能指针并创建克隆指针,而不是使用复制构造函数。

    克隆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 尝试使用默认的克隆?

    有人能澄清我做错了什么吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Community CDub    8 年前

    克隆体的类型硬编码为 default_clone ,而不是使用模板参数 Cloner (请参见类定义的最后一行)。

    编辑 只是为了确保你理解,你对 mCloner 应该如下所示:

    Cloner mCloner;
    

    这样,克隆器实际上就是模板参数指定的类型。

    还有一件事。如果你期望你 clone_ptr 要在更一般的环境中使用(例如,由其他项目的同事使用),您应该使克隆器的类型成为该类型的属性 T . 这可以通过使用类型特征来实现。( this answer 举个例子)。在你的 克洛尼 :

    template< typename T, typename Cloner = cloner_traits< T >::cloner_type >
    class clone_ptr {
        // ...
    };
    

    这将具有与当前实现相同的默认行为。其优点是需要特殊克隆的类只需要专门化 cloner_traits 模板和类的用户不必担心选择合适的克隆器。如果您仍然想为任何类重写克隆器,您仍然可以手动传递克隆器。

        2
  •  2
  •   David Maisonave    14 年前

    我建议在以下链接中使用clone_ptr类: http://www.codeproject.com/KB/stl/clone_ptr.aspx

    上述类型的克隆指针不需要具有克隆函数。 与上面的类型实现相比,这种类型的克隆指针类还有其他优点。

    有关详细信息,请参阅文章。