一个可以放入STL容器的简洁、高效、非计数的智能指针实现

       只要学过C++的都知道STL内有一个auto_ptr的智能指针实现,可惜的很这个智能指针和STL容器格格不入,无法和像vector、list、deque、map、set等这样关键性的容器配合使用,大大降低了auto_ptr的使用范围和应用范畴。至于boost库内倒是有share_ptr和weak_ptr这样的智能指针,但是boost库并非标准库,且实现比较复杂不比auto_ptr实现简单。为此我想和很多,难道真的没有一个简单的可以放置到容器内高效的的智能指针呢?最近有机会我终于实现了一个这样一个智能指针。其原理如下:

      首先,吸取auto_ptr的教训,将内存管理的句柄分为两个。一个负责持有对象,在必要时释放所持有的对象所占的空间。另一个则是负责供外面的用户使用,即使所持有的对象转移了依然不影响对源对象的使用。

      接着,吸取auto_ptr之所以高效的经验,采用持有对象转移策略。

      然后,将管理对象分治为管理一个对象和管理多个对象的方略,分别提供不同实现方法和操作以便更进一步降低复杂度。

      最后,将接口最小化,紧守本有功能,不提供额外功能,但是在力所能及的情况下提供足够便利的高效的功能。

      其具体实现代码如下:

auto_pointer.h

#ifndef __AUTO_POINTER_H__
#define __AUTO_POINTER_H__

//#include "debug_log.h"
#include <cassert>

用于代替std::auto_ptr,其接口设计与其保持兼容,用于管理单个对象
template <typename T>
class auto_pointer
{
public:
    typedef T element_type;

public:
    为了兼容原来的auto_ptr, 缺省构造函数
    auto_pointer() throw()
        :    m_uPtr(0)
        ,    m_aPtr(0)
    {
    }

    为了兼容原来的auto_ptr,单参数构造
    auto_pointer(element_type *p) throw()
        :    m_uPtr(p)
        ,    m_aPtr(p)
    {
    }

    复制构造函数
    一个本类对象传过来,接收方保存其对象的句柄值,源对象不再负责释放其对象句柄
    auto_pointer(const auto_pointer<element_type>& ref) throw()
        :    m_uPtr(release(&ref))
        ,    m_aPtr(m_uPtr)
    {
    }

    ~auto_pointer() throw()
    {
        reset(0);
    }

    auto_pointer<element_type>& operator =(const auto_pointer<element_type>& ref) throw()
    {
        reset(release(&ref));
        return *this;
    }

    const element_type& operator *() const throw()
    {
        assert(m_uPtr != 0);
        return *m_uPtr;
    }

    element_type& operator *() throw()
    {
        assert(m_uPtr != 0);
        return *m_uPtr;
    }

    const element_type* operator->() const throw()
    {
        return m_uPtr;
    }

    element_type* operator->() throw()
    {
        return m_uPtr;
    }

    element_type* get() const throw()
    {
        return m_uPtr;
    }

    const element_type* get() throw()
    {
        return m_uPtr;
    }

    void reset(element_type *p) throw()
    {
        if (m_aPtr)
        {
            //DEBUG_LOG("auto_pointer delete");
            delete m_aPtr;
        }
        
        m_uPtr = m_aPtr = p;
    }

    element_type *release() throw()
    {
        return release(this);
    }
    
private:
    将源对象的持有句柄置空,返回源对象的使用句柄
    static element_type *release(const auto_pointer<element_type> *ref) throw()
    {
        auto_pointer<element_type> *p = (const_cast< auto_pointer<element_type> *>(ref));
        p->m_aPtr = 0;
        return p->m_uPtr;
    }

private:
    element_type*    m_uPtr;
    element_type*    m_aPtr;
};

template <>
class auto_pointer<void>
{
public:
    typedef void element_type;
};

自动缓冲区类,是auto_pointer的多个对象版
template <typename T>
class auto_buffer
{
public:
    typedef unsigned int size_t;
    typedef T element_type;
    
public:
    缺省构造器
    auto_buffer() throw()
    :    m_uPtr(0)
    ,    m_aPtr(0)
    {
    }

    一般构造器
    auto_buffer(element_type *p) throw()
        :    m_uPtr(p)
        ,    m_aPtr(p)
    {
    }

    复制构造器
    一个本类对象传过来,接收方保存其对象的句柄值,源对象不再负责释放其对象句柄
    auto_buffer(const auto_buffer<element_type>& ref) throw()
        :    m_uPtr(release(&ref))
        ,    m_aPtr(m_uPtr)
    {
    }

    析构器
    ~auto_buffer() throw()
    {
        reset(0);
    }

    复制操作符
    auto_buffer<element_type>& operator =(const auto_buffer<element_type>& ref) throw()
    {
        reset(release(&ref), ref.m_size);
        return *this;
    }

    element_type* get() throw()
    {
        return m_uPtr;
    }
    
    const element_type* get() const throw()
    {
        return m_uPtr;
    }

    void reset(element_type *p) throw()
    {
        if (m_aPtr)
        {
            //DEBUG_LOG("auto_buffer delete");
            delete[] m_aPtr;
        }

        m_uPtr = m_aPtr = p;
    }

    element_type* release() throw()
    {
        return release(this);
    }
    
private:
    将源对象的持有句柄置空,返回源对象的使用句柄
    static
    element_type* release(const auto_buffer<element_type> *ref) throw()
    {
        auto_buffer<element_type> *p = (const_cast< auto_buffer<element_type> *>(ref));
        p->m_aPtr = 0;
        return p->m_uPtr;
    }

private:
    element_type*    m_uPtr;
    element_type*    m_aPtr;
};

template <>
class auto_buffer<void>
{
public:
    typedef void element_type;
};

#endif

end auto_pointer.h


debug_log.h

#ifndef __DEBUG_LOG_H_
#define __DEBUG_LOG_H_

//#include <qstring.h>

void debug_log(const char *_s);

//inline void debug_log(const QString& _s)
//{
//    debug_log(_s.toLocal8Bit().constData());
//}

#ifdef ENABLE_DEBUG_LOG
    #define DEBUG_LOG(a) debug_log(a)
    //#define DEBUG_LOG1(a)    DEBUG_LOG(QString(# a ":%1").arg(a))
    //#define DEBUG_LOG2(a, b)    DEBUG_LOG(QString(# a ":%1 " # b ":%2").arg(a).arg(b))
#else
    #define DEBUG_LOG(a)
    //#define DEBUG_LOG1(a)
    //#define DEBUG_LOG2(a, b)
#endif

#endif    //__DEBUG_LOG_H_
end debug_log.h

debug_log.cpp

#include "debug_log.h"
#include <cstdio>
#include <string>
#include <ctime>
//#include <cstdarg>
const std::string now_time()
{
    time_t _tim = time(0);
    std::string _stim(ctime(&_tim));
    return _stim.substr(0, _stim.size() - 1);
}

void debug_log(const char *s)
{
    FILE *_out = fopen("c:/debug_log.log", "a+");
    if (_out)
    {
        fprintf(_out, "%s %s\n", now_time().c_str(), s);
        fclose(_out);
    }
}

end debug_log.cpp


main.cpp

#include "auto_pointer.h"
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>

struct a
{
    a(int _base = 0, const std::string& _s = "")
    :    base(_base)
    ,    s(_s)
    {
    }
    
    int base;
    std::string s;
};

std::string to_str(int _value)
{
    char buffer[256] = {0};
    sprintf(buffer, "%d", _value);
    return buffer;
}

int main(int argc, char *argv[])
{
    /*auto_pointer<int> ap1(new int(1978));
    auto_pointer<int> ap2(new int);
    *ap2 = 110;
    std::cout << "ap1:" << *ap1 << ", ap2:" << *ap2 << std::endl;
    ap2 = ap1;
    std::cout << "ap1:" << *ap1 << ", ap2:" << *ap2 << std::endl;
    
    auto_pointer<a> p1(new a(100, "wps"));
    std::cout << "base:" << p1->base << ", s:" << p1->s << std::endl;
    */
    
    /*typedef std::vector< auto_pointer<a> > ints_t;
    ints_t va;
    for (int i = 0; i < 100; ++i)
    {
        va.push_back(new a(i, to_str(i << 1)));
    }
    */
    
    typedef auto_buffer<int> ints_t;
    ints_t v(new int[100]);
    int i = 0;
    for (int *begin = v.get(), *end = begin + 100; begin != end; ++begin)
    {
        *begin = i++;
    }
    
    //int i = 0;
    for (const int *begin = v.get(), *end = begin + 100; begin != end; ++begin)
    {
        std::cout << *begin << std::endl;
        //*begin = 123;
    }
    
    typedef std::vector< auto_buffer<int> > va_t;
    va_t va;
    for (int i = 0; i < 10; ++i)
    {
        auto_buffer<int> buf(new int[10]);
        for (int *begin = buf.get(), *end = begin + 10; begin != end; ++begin)
        {
            *begin = i;
        }
        va.push_back(buf);
    }
    return 0;
}

end main.cpp

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值