字符串类中重载运算符

 测试程序

/// @file exam_1_1.cpp
/**
1.完善MyString, 引用计数RefMyString
operator=
operator+
operator[](int nIndex)
operator==
operator!=
operator>
*/

#include "common.h"
#include "MyString.h"

void fnTestString();
void clear_cin();

int main(int argc, char** argv, char** envp)
{
    fnTestString();

    cout << "END, press any key to quit" << endl;
    clear_cin();
    getchar();

    return 0;
}

void fnTestString()
{
    CMyString str("hello");
    CMyString str1(str);
    CMyString str2 = CMyString("hello world");

    str1 = "vc6";
    cout << str1 << endl;

    str2 += " vc6";
    cout << str2 << endl;

    str1 = str2 + " c++";
    cout << str1.c_str() << endl;
    cout << (str1 >= "hello") << endl;

    cout << str[2] << endl;
    cout << str[-1] << endl;

    cout << str.c_str() << endl;
    cout << (str2 > NULL) << endl;
    cout << (str2 >= "hello") << endl;
    cout << (str2 < "hello") << endl;
    cout << (str2 <= "hello") << endl;
    cout << (str2 == "hello") << endl;
    cout << (str2 != "hello") << endl;

    cout << str2.StringFormatV("test %d", 1) << endl;
}

void clear_cin()
{
    cin.clear();
    cin.sync();
}

公用头文件

/// @file common.h
/// @brief 公用头文件

#ifndef COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316
#define COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316

#include <iostream>
#include <limits>
#include <string>

#include <crtdbg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>

using namespace std;

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif // #ifndef BOOL

#ifndef NULL
#define NULL 0
#endif // #ifndef NULL

#ifndef SAFE_DELETE
#define SAFE_DELETE(x) \
{ \
    if (NULL != (x)) \
    { \
        delete (x); \
        (x) = NULL; \
    } \
}
#endif // #ifndef SAFE_DELETE

#ifndef SAFE_DELETE_ARY
#define SAFE_DELETE_ARY(x) \
{ \
    if (NULL != (x)) \
    { \
        delete[] (x); \
        (x) = NULL; \
    } \
}
#endif // #ifndef SAFE_DELETE_ARY

#endif // #ifndef COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316

RefCount.h

// RefCount.h: interface for the CRefCount class.
//
//

#if !defined(AFX_REFCOUNT_H__2F7675D6_BDC0_4BE6_A0FD_14F51476D8ED__INCLUDED_)
#define AFX_REFCOUNT_H__2F7675D6_BDC0_4BE6_A0FD_14F51476D8ED__INCLUDED_

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

#include "common.h"
#include "MyString.h"

class CMyString;
class CRefCount  
{
public:
	CRefCount(CMyString* pOwner);
    CRefCount(const CRefCount* pObj);
    CRefCount(const CRefCount& Obj);
	virtual ~CRefCount();

    void addRef(); ///< 引用计数++
    int releaseRef(); ///< 引用计数--
    int* getRefCount() {return m_piRefCount;}
    CMyString* getOwner() {return m_pOwner;}

private:
    void cpyAndAddRef(const CRefCount* pObj);

private:
    int* m_piRefCount; ///< 引用计数点数指针
    CMyString* m_pOwner; ///< 引用计数所有者指针
};

#endif // !defined(AFX_REFCOUNT_H__2F7675D6_BDC0_4BE6_A0FD_14F51476D8ED__INCLUDED_)

MyString.h

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

#if !defined(AFX_MYSTRING_H__F5118BD7_4C05_47F1_AD8E_D18B1F44B0CA__INCLUDED_)
#define AFX_MYSTRING_H__F5118BD7_4C05_47F1_AD8E_D18B1F44B0CA__INCLUDED_

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

#include "common.h"
#include "RefCount.h"

class CRefCount;
class CMyString  
{
    /// 构造函数, 析构函数, 拷贝构造函数
public:
	CMyString();
    CMyString(const char* psrc);
	virtual ~CMyString();

    CMyString(CMyString& src);
    CMyString(CMyString* psrc);

    /// 转换运算符重载

    /// 运算符重载
    void operator = (const char* pSrc);
    CMyString operator + (const char* pSrc);
    CMyString& operator += (const char* pSrc);
    bool operator > (const char* pSrc);
    bool operator >= (const char* pSrc);
    bool operator < (const char* pSrc);
    bool operator <= (const char* pSrc);
    bool operator == (const char* pSrc);
    bool operator != (const char* pSrc);
    const char* operator [] (size_t nIndex) const;

    /// 成员方法
    virtual BOOL IsRefCountNULL();
    virtual CRefCount* getRefCount() {return m_pRefCount;}

    const char* c_str() const;
    const char* StringFormatV(char* szFormat, ...);

private:
    virtual CMyString* strcat(const char* pSrc);
    void setString(const char* pSrc);
    CMyString* strcpy(const char* pSrc);
    int compare(const char* pSrc);

    void init(CMyString* pRefOwner);
    void init_refcount(CMyString* pRefOwner);
    void uninit();
    BOOL uninit_refcount();

    // member data
private:
    char* m_lpString; ///< 开辟(new)的字符串缓冲区
    int   m_nLen; ///< 字符串长度

    /// 如果最终要操作的字符串比缓冲区小, 就不用另外再开辟缓冲区了
    int   m_nSpaceLen; ///< 缓冲区总长度

    CRefCount* m_pRefCount; ///< 引用计数
};

ostream& operator<< (ostream& cout, CMyString& right);

#endif // !defined(AFX_MYSTRING_H__F5118BD7_4C05_47F1_AD8E_D18B1F44B0CA__INCLUDED_)

MyString.cpp

// MyString.cpp: implementation of the CMyString class.
//
//

#include "MyString.h"

//
// Construction/Destruction
//

CMyString::CMyString()
: m_pRefCount(NULL)
{
    init(this);
}

CMyString::~CMyString()
{
    uninit();
}

CMyString::CMyString(CMyString& src)
: m_pRefCount(NULL)
{
    init(&src);
    this->strcpy(src.c_str());
}

CMyString::CMyString(CMyString* psrc)
: m_pRefCount(NULL)
{
    init(psrc);

    if (NULL != psrc)
    {
        this->strcpy(psrc->c_str());
    }
}

CMyString::CMyString(const char* psrc)
: m_pRefCount(NULL)
{
    init(this);

    if (NULL != psrc)
    {
        this->strcpy(psrc);
    }
}

void CMyString::operator = (const char* pSrc)
{
    strcpy(pSrc);
}

CMyString CMyString::operator + (const char* pSrc)
{
    CMyString tmp;

    tmp = *this;
    tmp += pSrc;
    return tmp;
}

CMyString& CMyString::operator += (const char* pSrc)
{
    strcat(pSrc);
    return *this;
}

const char* CMyString::operator [] (size_t nIndex) const
{
    char* pRc = "";

    if ((NULL != m_lpString) 
        && (nIndex >= 0) 
        && (nIndex < strlen(m_lpString)))
    {
        pRc = m_lpString + nIndex;
    }

    return pRc;
}

int CMyString::compare(const char* pSrc)
{
    int iRc = 0;
    const char * pMe = (NULL != m_lpString) ? m_lpString : "";
    const char * pSrcCpy = (NULL != pSrc) ? pSrc : "";
    
    /// strcmp入参为空指针会报错
    iRc = ::strcmp(pMe, pSrcCpy);

    return iRc;
}

bool CMyString::operator > (const char* pSrc)
{
    return (compare(pSrc) > 0);
}

bool CMyString::operator >= (const char* pSrc)
{
    return (compare(pSrc) >= 0);
}

bool CMyString::operator < (const char* pSrc)
{
    return (compare(pSrc) < 0);
}

bool CMyString::operator <= (const char* pSrc)
{
    return (compare(pSrc) <= 0);
}

bool CMyString::operator == (const char* pSrc)
{
    return (compare(pSrc) == 0);
}

bool CMyString::operator != (const char* pSrc)
{
    return (compare(pSrc) != 0);
}

void CMyString::init(CMyString* pRefOwner)
{
    if (NULL != pRefOwner)
    {
        m_lpString = NULL;
        m_nLen = 0;
        m_nSpaceLen = 0;
        
        init_refcount(pRefOwner);

    }
}

BOOL CMyString::IsRefCountNULL()
{
    if (NULL == m_pRefCount)
    {
        return TRUE;
    }
    
    return (NULL == m_pRefCount->getRefCount());
}

void CMyString::init_refcount(CMyString* pRefOwner)
{
    if (NULL == m_pRefCount)
    {
        m_pRefCount = new CRefCount(pRefOwner);
    }

    if (NULL != m_pRefCount)
    {
        m_pRefCount->addRef();
    }
}

void CMyString::uninit()
{
    if (uninit_refcount())
    {
        SAFE_DELETE_ARY(m_lpString);
    }

    SAFE_DELETE(m_pRefCount);
}

BOOL CMyString::uninit_refcount()
{
    BOOL bRc = FALSE;
    
    if (NULL != m_pRefCount)
    {
        bRc = (0 == m_pRefCount->releaseRef());
    }
    
    return bRc;
}

void CMyString::setString(const char* pSrc)
{
    this->strcpy(pSrc);
}

const char* CMyString::c_str() const
{
    if (NULL == m_lpString)
    {
        return "";
    }
    else
    {
        return m_lpString;
    }
}

CMyString* CMyString::strcpy(const char* pSrc)
{
    int iLenNew = 0;
    char* pNewString = NULL;
    if (NULL == pSrc)
    {
        return this;
    }
    
    iLenNew = ::strlen(pSrc);
    if (iLenNew > (m_nSpaceLen - 1))
    {
        pNewString = new char[iLenNew + 1];
        _ASSERT(NULL != pNewString);

        pNewString[0] = '\0';
        ::strcpy(pNewString, pSrc);
        SAFE_DELETE_ARY(m_lpString);
        
        m_nLen = iLenNew;
        m_nSpaceLen = m_nLen + 1;
        m_lpString = pNewString;
    }
    else
    {
        m_nLen = strlen(pSrc);
        _ASSERT(NULL != m_lpString);

        if (0 != ::strcmp(m_lpString, pSrc))
        {
            ::strcpy(m_lpString, pSrc);
        }
    }

    return this;
}

CMyString* CMyString::strcat(const char* pSrc)
{
    int iLenNew = 0;
    char* pNewString = NULL;
    if (NULL == pSrc)
    {
        return this;
    }

    if (NULL == m_lpString)
    {
        this->strcpy(pSrc);
        return this;
    }

    iLenNew = m_nLen + strlen(pSrc);
    if (iLenNew > (m_nSpaceLen - 1))
    {
        pNewString = new char[iLenNew + 1];
        pNewString[0] = '\0';
        ::strcpy(pNewString, m_lpString);
        SAFE_DELETE_ARY(m_lpString);
        ::strcat(pNewString, pSrc);

        m_nLen = iLenNew;
        m_nSpaceLen = m_nLen + 1;
        m_lpString = pNewString;
    }
    else
    {
        m_nLen += strlen(pSrc);
        ::strcat(m_lpString, pSrc);
    }

    return this;
}

const char* CMyString::StringFormatV(char* szFormat, ...)
{
    size_t nStrLen = 1024 * 100; ///< 默认开100K空间
    va_list args;
    char* pNewString = NULL;
    
    va_start(args, szFormat);
    
    /**
    _MSC_VER Defines the compiler version. 
    Defined as 1200 for Microsoft Visual C++ 6.0. Always defined. 
    */
    if (_MSC_VER > 1200)
    {
        /// vs6不允许这么用, vs2010可以
        /// 估算需要的缓冲区长度
        nStrLen = _vsnprintf(NULL, 0, szFormat, args);
    }
    
    pNewString = new char[nStrLen + 1];
    _ASSERT(pNewString);
    ::memset(pNewString, 0, (nStrLen + 1) * sizeof(char));
    
    nStrLen = _vsnprintf(pNewString, nStrLen, szFormat, args);
    va_end(args);

    this->strcpy(pNewString);
    return this->c_str();
}

ostream& operator<< (ostream& cout, CMyString& right)
{
    cout << right.c_str();
    return cout;
}

RefCount.cpp

// RefCount.cpp: implementation of the CRefCount class.
//
//

#include "RefCount.h"

//
// Construction/Destruction
//

using namespace std;

CRefCount::CRefCount(CMyString* pOwner)
:m_piRefCount(NULL)
,m_pOwner(NULL)
{
    if (NULL != pOwner)
    {
        if (pOwner->IsRefCountNULL())
        {
            m_piRefCount = new int(0);
        }
        else
        {
            m_piRefCount = pOwner->getRefCount()->getRefCount();
        }
        m_pOwner = pOwner;
        addRef();
    }
}

CRefCount::CRefCount(const CRefCount* pObj)
{
    cpyAndAddRef(pObj);
}

CRefCount::CRefCount(const CRefCount& Obj)
{
    cpyAndAddRef(&Obj);
}

void CRefCount::cpyAndAddRef(const CRefCount* pObj)
{
    if ((NULL == pObj) || (this == pObj))
    {
        return;
    }
    
    m_piRefCount = pObj->m_piRefCount;
    m_pOwner = pObj->m_pOwner;
    addRef();
}

CRefCount::~CRefCount()
{
    if (0 == releaseRef())
    {
        if (NULL != m_pOwner)
        {
            /// CRefCount作为m_pOwner中的一个new出来的指针
            /// 这里不能删除m_pOwner
            /// 会引起递归调用
            /// 只能将m_pOwner置为空
            /// 让调用者显式释放m_pOwner
            m_pOwner = NULL;
        }

        if (NULL != m_piRefCount)
        {
            delete m_piRefCount;
            m_piRefCount = NULL;
        }
    }
}

void CRefCount::addRef()
{
    int iRc = 0;

    if (NULL != m_piRefCount)
    {
        (*m_piRefCount)++;
        iRc = *m_piRefCount;
    }
}

int CRefCount::releaseRef()
{
    int iRc = 0;

    iRc = (NULL != *m_piRefCount) ? (--(*m_piRefCount)) : 0;
    return iRc;
}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值