Chinaunix首页 | 论坛 | 博客
  • 博客访问: 311784
  • 博文数量: 174
  • 博客积分: 130
  • 博客等级: 入伍新兵
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-12 19:39
文章分类

全部博文(174)

文章存档

2018年(2)

2016年(10)

2015年(6)

2014年(31)

2013年(92)

2012年(33)

我的朋友

分类: C/C++

2014-06-17 23:18:05

1.2 重载操作符new/delete实现内存监控

由于C++使用new/delete来分配/释放内存,所以可以通过重载new/delete来监控本模块的内存使用情况,比如检测内存泄漏。


//Define a big enough global table.


void *operator new(size_t size)

{

            void *p = malloc(size);

            record p in the global table; //If multithreads, mutex needed


            return p;

}

void operator delete(void *p)

{

            remove the record from global table; //If multithreads, mutex needed


            free(p);

}


程序可以定期打印出global table内容以查看有无泄漏。

 

1.3 智能指针(Smart Pointer

智能指针是对原始指针(Raw Pointer)的智能管理,它对原始指针进行引用计数,对指针的拷贝、销毁进行监控,只有在引用计数为0时才真正删除,同时还可以预防空指针的访问。智能指针提高了指针使用的安全性,而且还可以在一定程度上像Java一样做到内存回收,避免了内存泄漏。

SmartPtr.h




class Target;

/** This class represents a smart pointer to Target. */
class SmartPtr
{
public:

    /** Default constructor */
    SmartPtr();
    
    /** Copy Constructor */
    SmartPtr( const SmartPtr& tg);
    
    
    /** Construct smart pointer from a new target */
    SmartPtr(Target* target);
    
    
    /** Destructor */
    ~SmartPtr();
    
    // Assignment operator

    SmartPtr& operator=(const SmartPtr& p);
    
    // Assignment operator

    SmartPtr& operator=(Target* p);

    /** Returns true if the smart pointer has not been initialized with
     * a target.
     */

    bool isNil();

    /** Make the smart pointer uninitialized (i.e., the smart pointer is no longer pointing
     * to any target object.
     */

    void nil();
    
    Target* operator->() const;
    
    private:
    // Pointer to actual object

    Target* m_tgtPtr;

};



SmartPtr.cpp




#include "/Target.h"
#include "SmartPtr.h"

SmartPtr::SmartPtr()
{
        // This initializes the object pointer to null.

        m_tgtPtr = (Target *)0L;
}

SmartPtr::SmartPtr(const SmartPtr& dp )
{
    m_tgtPtr = (Target *)0L;     

    /* This next statement uses the overloaded operator=(SmartPtr&) defined below
     * to decrement the reference count for the
     * old Target object used by this class and increment the
     * usage count for the new Target object.
     */

    *this = dp;
}

SmartPtr::SmartPtr( Target *dp )
{
    m_tgtPtr = (Target *)0L;

    /* This next statement uses the overloaded operator=(Target *) defined below
     * to decrement the reference count for the
     * old Target object used by this class and increment the
     * usage count for the new Target object.
     */

    *this = dp;
}

SmartPtr::~SmartPtr()
{
    // This will cause a decrement of the Target reference count

    // via the operator=(Target *) defined below


    *this = (Target *) 0L;
}

SmartPtr& SmartPtr::operator= (const SmartPtr& newPtr)
{
    // This has the effect of calling the overloaded operator=(Target *)

    // method which adjusts the Target reference count

    *this = newPtr.m_tgtPtr;

    return *this;
}


bool SmartPtr::isNil()
{
    return( ( dPtr == 0L ) );
}

void SmartPtr::nil()
{
    // This will cause a decrement of the Target reference count

    // via the operator=(Target *) defined below


    *this = 0L;

}


// This overloading will allow the user of this handle to access public

// methods and data members of Target, as though they were members of SmartPtr.

// For example, where you might do a req->setX() you can do a reqPtr->setX() with the same

// effect

Target *SmartPtr::operator-> () const
{
    return(m_tgtPtr);
}

SmartPtr& SmartPtr::operator= (Target *newTgt)
{
    /* This method is the main method keeping track of the
     * reference count for the associated Target object.
     */


    // If the pointer passed is not null then bump up the reference

    // count for the source Target.

    if(newTgt != 0L )
    {
        newTgt->incrRefCount();
    }

    // If the pointer this object is currently using is not null

    // then decrement the count for that pointer.

    if(m_tgtPtr != 0L ) {

        // If the count has reached zero, then it is time to delete this

        // object

        if(m_tgtPtr->decrRefCount() == 0 )
        {
            delete m_tgtPtr;
        }
    }

    // Have this smart pointer now point to the new Target object.

    m_tgtPtr = newTgt;

    return(*this);
}



Target.h


#include “SmartPtr.h”
class Target
{
public:
    Target()
    {
        m_refCount = 0;
    }

    virtual ~Target();
    void DoSth();
protected:
    friend class SmartPtr;
    int incrRefCount()
    {
        return ++m_refCount; //Mutex protection needed for multi-threads

    }

int decrRefCount()
{
    if(--m_refCount < 0) //Mutex protection needed for multi-threads

        m_refCount = 0;
    return m_refCount;
}

int m_refCount;
//Add mutex for multi-threads

};

Target::~Target()
{
    m_refCount = 0;
}



使用示例


void Foo()
{
Target *p = new Target();
SmartPtr sp(p);
SmartPtr sp2 = p; //p’s reference count is 2

sp->DoSth();
sp2->DoSth();        // p will be destroyed automatically after function returns

}



任何需要做成智能指针的对象,都可以从Target派生。

 

1.4 STL

模板是一种泛型编程概念。通过使用模板可以使程序具有更好的代码重用性。模板是对源代码进行重用,而不是通过继承和组合重用对象代码,当用户使用模板时,参数由编译器来替换。

 

泛型编程和面向对象编程不同,它并不要求你通过额外的间接层来调用函数,它让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。所谓泛型(Generic),是指具有在多种数据类型上皆可操作的含意。

 

STL(Standard Template Library,标准模板库) 是泛型编程的一个代表作品。STL是一个容器(Container)的集合(比如listvector),它的主要概念是ContainterIterator。它使用很方便,而且效率很高。

 

严格而言,STL并不是面向对象的概念,它属于C++的一个特色(现在Java6中也引入了STL)。




《返璞归真--UNIX技术内幕》在全国各大书店及网城均有销售:
亚马逊                          China pub
上学吧                          1号店


阅读(629) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册