• QScopedPointer 源码剖析


    析构时候清除pointer

    template <typename T>
    struct QScopedPointerDeleter
    {
        static inline void cleanup(T *pointer)
        {
            // Enforce a complete type.
            // If you get a compile error here, read the secion on forward declared
            // classes in the QScopedPointer documentation.

    //检查类型是否完整,编译期间检查
            typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
            (void) sizeof(IsIncompleteType);

            delete pointer;
        }
    };

    template <typename T>
    struct QScopedPointerArrayDeleter
    {
        static inline void cleanup(T *pointer)
        {
            // Enforce a complete type.
            // If you get a compile error here, read the secion on forward declared
            // classes in the QScopedPointer documentation.
            typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
            (void) sizeof(IsIncompleteType);

            delete [] pointer;
        }
    };

    struct QScopedPointerPodDeleter
    {
        static inline void cleanup(void *pointer) { if (pointer) qFree(pointer); }
    };

    template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
    class QScopedPointer
    {
    #ifndef Q_CC_NOKIAX86
        typedef T *QScopedPointer:: *RestrictedBool;
    #endif
    public:
        explicit inline QScopedPointer(T *p = 0) : d(p)
        {
        }

        inline ~QScopedPointer()
        {
            T *oldD = this->d;
            Cleanup::cleanup(oldD);
            this->d = 0;
        }

        inline T &operator*() const
        {
            Q_ASSERT(d);
            return *d;
        }

        inline T *operator->() const
        {
            Q_ASSERT(d);
            return d;
        }

        inline bool operator!() const
        {
            return !d;
        }

    #if defined(Q_CC_NOKIAX86) || defined(Q_QDOC)
        inline operator bool() const
        {
            return isNull() ? 0 : &QScopedPointer::d;
        }
    #else
        inline operator RestrictedBool() const
        {
            return isNull() ? 0 : &QScopedPointer::d;
        }
    #endif

        inline T *data() const
        {
            return d;
        }

        inline bool isNull() const
        {
            return !d;
        }

        inline void reset(T *other = 0)
        {
            if (d == other)
                return;
            T *oldD = d;
            d = other;
            Cleanup::cleanup(oldD);
        }

        inline T *take()
        {
            T *oldD = d;
            d = 0;
            return oldD;
        }

        inline void swap(QScopedPointer<T, Cleanup> &other)
        {
            qSwap(d, other.d);
        }

        typedef T *pointer;

    protected:
        T *d;

    private:
        Q_DISABLE_COPY(QScopedPointer)
    };

    template <class T, class Cleanup>
    inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
    {
        return lhs.data() == rhs.data();
    }

    template <class T, class Cleanup>
    inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
    {
        return lhs.data() != rhs.data();
    }

    template <class T, class Cleanup>
    Q_INLINE_TEMPLATE void qSwap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2)
    { p1.swap(p2); }

    template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
    class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
    {
    public:
        explicit inline QScopedArrayPointer(T *p = 0)
            : QScopedPointer<T, Cleanup>(p)
        {
        }

        inline T &operator[](int i)
        {
            return this->d[i];
        }

        inline const T &operator[](int i) const
        {
            return this->d[i];
        }

    private:
        Q_DISABLE_COPY(QScopedArrayPointer)
    };

    #define Q_DISABLE_COPY(Class) \
        Class(const Class &); \
        Class &operator=(const Class &);

    声明拷贝和赋值函数为私有

    --------------------------------

    参考

    C++ template Day Day Up 第四天 Boost::checked_delete

    //DeleteObject.h

    class Item;

    class DeleteObject
    {
    public:
        DeleteObject(void);
    public:
    ~DeleteObject(void);

    void DeleteItem(Item* p);
    };

    //DeleteObject.cpp

    #include "StdAfx.h"
    #include "DeleteObject.h"
    #include <boost/checked_delete.hpp>

    DeleteObject::DeleteObject(void)
    {
    }

    DeleteObject::~DeleteObject(void)
    {
    }

    void DeleteObject::DeleteItem( Item* p )
    {
        delete p;
    }

    //item.h

    #include <iostream>

    class Item
    {
    public:
    ~Item()
    {
            std::cout<<"Item destruction ";
        }
    };

    //main.cpp

    #include "DeleteObject.h"
    #include "Item.h"

    DeleteObject del;
    del.DeleteItem(new Item);

    /////////////////////////////////

    结果Item的析构函数没有被调用~

    这是因为DeleteObject并不知道Item的详细定义,这是C++中一个很危险的错误!(还好编译器一般都给warning)

    怎么解决这个问题呢?

    利用Boost库中的checked_delete

    定义如下:

    template<class T> inline void checked_delete(T * x)
    {
    // intentionally complex - simplification causes regressions
        typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
        (void) sizeof(type_must_be_complete);
        delete x;
    }

    template<class T> inline void checked_array_delete(T * x)
    {
        typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
        (void) sizeof(type_must_be_complete);
        delete [] x;
    }

    可以看到利用C的一个语法——数组长度必须大于零,来解决这个问题,typedef是发生在编译期,而sizeof同样是在编译期,所以这两行代码不会对程序的效率空间等等产生任何影响,只会在上面所举的例子发生的时候报编译错误。

    现在将代码改为:

    void DeleteObject::DeleteItem( Item* p )
    {
        boost::checked_delete(p);
    }

  • 相关阅读:
    数学图形之心形
    Nginx中文文档-安装 Nginx
    Mysql的row_format
    layui问题之模拟select点击事件
    深入理解HTTP协议、HTTP协议原理分析
    file_get_contents("php://input")的用法
    如何创建自己的composer包
    解决git pull/push每次都需要输入密码问题 和 HttpRequestException encountered
    微信网页授权 通过code获取openid 报错40163 code been used
    Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'userinfo.
  • 原文地址:https://www.cnblogs.com/cute/p/1968089.html
Copyright © 2020-2023  润新知