引用计数

// CMyString.h: interface for the CMyString class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CMYSTRING_H__FECC10BF_AB85_41AB_B3F3_7A16FA65D4AF__INCLUDED_)
#define AFX_CMYSTRING_H__FECC10BF_AB85_41AB_B3F3_7A16FA65D4AF__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "CRefCount.h"

class CMyString 
{
public:
CMyString();
CMyString(const char* pSzData);
CMyString(const CMyString& obj);
void SetData(const char* pSzData);
void Print() const;
~CMyString();
private:
CRefCount* m_cRef;
};

#endif // !defined(AFX_CMYSTRING_H__FECC10BF_AB85_41AB_B3F3_7A16FA65D4AF__INCLUDED_)
// CMyString.cpp: implementation of the CMyString class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CMyString.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMyString::CMyString()
{
  m_cRef = NULL;
}

CMyString::~CMyString()
{
  if (m_cRef != NULL)
  {
    m_cRef->RefDec();
    m_cRef = NULL;
  }
}

CMyString::CMyString(const char *pSzData)
{
  m_cRef = CRefCount::CreatClass(pSzData);
}

CMyString::CMyString(const CMyString& obj)
{
  m_cRef = obj.m_cRef;

  if (m_cRef != NULL)
  {
    m_cRef->RefAdd();
  }
}

void CMyString::SetData(const char* pSzData)
{
  if (m_cRef == NULL)
  {
    m_cRef = CRefCount::CreatClass(pSzData);
  }
  else
  {
    m_cRef->SetData(pSzData);
  }
}

void CMyString::Print() const
{
  if (!m_cRef)
  {
    return;
  }
  m_cRef->Print();
}
// CRefCount.h: interface for the CRefCount class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CREFCOUNT_H__DEED2C87_0696_4C7B_95BE_21CB60D47ABC__INCLUDED_)
#define AFX_CREFCOUNT_H__DEED2C87_0696_4C7B_95BE_21CB60D47ABC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMyString;

class CRefCount  
{
  friend class CMyString;
private:
  static CRefCount* CreatClass(const char* pSzData);
    CRefCount();
  CRefCount(const char* pSzData);
    ~CRefCount();
  void Init();
  int RefAdd();
  int RefDec();
  void SetData(const char* pSzData);
  void Print() const;
private:
  char* m_pSzData;
  int   m_iStrLen;
  int   m_iSpaceLen;
  int   m_iRefCount;
};

#endif // !defined(AFX_CREFCOUNT_H__DEED2C87_0696_4C7B_95BE_21CB60D47ABC__INCLUDED_)
// CRefCount.cpp: implementation of the CRefCount class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CRefCount.h"
#include <string.h>
#include <stdlib.h>
#include <iostream.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRefCount::CRefCount()
{
  Init();
}

CRefCount::CRefCount(const char* pSzData)
{
  Init();
  SetData(pSzData);
}

CRefCount::~CRefCount()
{
  if (m_pSzData != NULL)
  {
    delete[] m_pSzData;
    m_pSzData = NULL;
  }
  m_iRefCount = 0;
  m_iSpaceLen = 0;
  m_iStrLen   = 0;
}

CRefCount* CRefCount::CreatClass(const char* pSzData)
{
  return new CRefCount(pSzData);
}

void CRefCount::Init()
{
  m_iSpaceLen = 0;
  m_iStrLen = 0;
  m_iRefCount = 1;
  m_pSzData = NULL;
}

int CRefCount::RefAdd()
{
  return ++m_iRefCount;
}

int CRefCount::RefDec()
{
  if (0 == --m_iRefCount)
  {
    delete this;
    // 这句有必要加上,因为对象释放了,也就不存在m_iRefCount
    return 0;
  }
  return m_iRefCount;
}


void CRefCount::SetData(const char* pSzData)
{
  if (m_pSzData != NULL)
  {
    delete[] m_pSzData;
    m_pSzData = NULL;
  }
  
  // 申请空间,失败则程序退出 
  int iStrLen = strlen(pSzData) + sizeof(char);
  m_pSzData = new char[iStrLen];
  
  if (!m_pSzData)
    exit(-1);
  
  memcpy(m_pSzData, pSzData, iStrLen);
  m_iStrLen = iStrLen - 1;
  m_iSpaceLen = iStrLen;
}

void CRefCount::Print() const
{
  if (!m_pSzData)
  {
    return;
  }
  cout << m_pSzData << endl;
}

还有一种写时引用计数,比如有3个对象共享数据。

其中一个修改不会影响其他两个的数据。

posted @ 2013-05-05 21:34  0x苦行僧  阅读(220)  评论(0编辑  收藏  举报