28_拷贝构造与动态字符串

拷贝构造

  1. 先实例化先构造
  2. 把实例化的一个对象赋值的给另一个对象的时候相当于memcpy //造成重复释放与没有释放
  3. 和构造函数一样,不过参数是当前类对象的引用
  4. 数据成员有指针需要使用
  5. 语法

CLASS cs;

CLASS cs2 = cs;      //拷贝构造

浅拷贝

  1. 直接拷贝所有相等的,会造成重复释放,VS默认拷贝构造为浅拷贝

深拷贝

  1. 堆空间重新申请,指向不一样的堆空间

动态字符串的封装

  1. 动态字符串(输入多大申请多大),能想到的字符串操作
    • 拷贝
    • 长度
    • 拼接
    • 大小写
    • 子串(反向查找)
    • 查找位置(库函数都是从左向右,可以方向查找)
    • 比较
    • 类型转换
    • 清空
    • 格式化
    • 回文检测
    • 制定位置插入字符串
    • 删除子串
    • 替换字符串
  2. 成员属性
    • 字符串指针
    • 字符串实际使用大小
    • 字符串界限
    • 字符串为空标记
  3. 函数成员
    • 设置字符串缓存
    • 获取字符串缓冲
    • 获取边界
    • 设置边界
    • 设置长度
    • 获取长度
    • 是否为空

作业

//CMyString.h
#pragma once

class CMyString
{
public:
    CMyString();    //无参构造
    CMyString(const char *str); //有参构造
    CMyString(CMyString& str);   //拷贝构造
    ~CMyString();   //析构
    unsigned getLength() const; //获取实际使用长度
    CMyString& myStrcpy(CMyString& str);    //拷贝字符串
    CMyString& myStrcat(CMyString& str);    //拼接字符串
    CMyString& myStrUpper();    //转换为大写
    CMyString& myStrLower();    //转换为小写
    const char *myFindSubStr(CMyString& str);    //查找子串-反向
    void myStrClear();  //清空
    const char *getBuff();  //获取字符串内存
    const char *getSubStrPointer(CMyString& str);   //查找位置 反向查找
    const int myStrcmp(CMyString& str);   //比较字符串
    const bool checkIsPlalindrome();    //检测是否为回文
    CMyString& myInsertStr(unsigned num, CMyString str);//指定位置插入字符串
    CMyString& myDeleteSubStr(CMyString str);//删除子串
    CMyString& myAlterChar(unsigned num, char ch);    //替换字符
    CMyString& myAlterStr(unsigned num, char ch);    //替换字符串
    CMyString& mySplitStr();//字符串分割 hello | world | test
private:
    char*& getStr(); //获取字符串
    unsigned getSize() const; //获取实际占用大小
    void setStr(const char *str);  //设置字符串
    void setLength(const unsigned length); //设置实际占用长度
    void setSize(const unsigned size); //设置实际占用空间大小
    bool getIsNull() const;   //检查是否为空
    void setIsNull(bool b);   //设置是否为空
    void initString(const char *str = nullptr); //初始化字符串
private:
    char *m_pStr; //指向字符串的数组
    unsigned m_uLenth;   //字符串的实际使用长度
    unsigned m_uSize;    //字符串的实际占用的内存大小
    bool m_bIsNull; //是否为空标记
};
//CMyString.cpp
#include "CMyString.h"
#include 

CMyString::CMyString()
{
    initString();
}

CMyString::CMyString(CMyString& str)
{
    if (str.getIsNull() == true)
    {
        initString();
    }
    else
    {
        initString(str.getStr());
    }
}

CMyString::CMyString(const char *str)
{
    initString(str);
}

CMyString::~CMyString()
{
    if (getIsNull() == true)
    {
        return;
    }
    else
    {
        delete[] getStr();
        setIsNull(true);
        setLength(0U);
        setSize(0U);
    }
}

inline char*& CMyString::getStr()
{
    return m_pStr;
}

inline unsigned CMyString::getLength() const
{
    return m_uLenth;
}

inline unsigned CMyString::getSize() const
{
    return m_uSize;
}

inline void CMyString::setStr(const char *str)
{
    strcpy(getStr(), str);
}

inline void CMyString::setLength(const unsigned length)
{
    m_uLenth = length;
}

inline void CMyString::setSize(const unsigned size)
{
    m_uSize = size;
}

inline bool CMyString::getIsNull() const
{
    return m_bIsNull;
}

inline void CMyString::setIsNull(bool b)
{
    m_bIsNull = b;
}

CMyString& CMyString::myStrcpy(CMyString& str)
{
    if (getIsNull())
    {
        if (!str.getIsNull())
        {
            initString(str.getStr());
        }
    }
    else
    {
        if (str.getIsNull())
        {
            setIsNull(true);
        }
        else
        {
            unsigned uLen = str.getLength() + 1U;
            if (getSize() >= uLen)
            {
                setStr(str.getStr());
                setLength(str.getLength());
            }
            else
            {
                delete[] getStr();
                initString(str.getStr());
            }
        }
    }

    return *this;
}

CMyString& CMyString::myStrcat(CMyString& str)
{
    if (getIsNull())
    {
        if (!str.getIsNull())
        {
            initString(str.getStr());
        }
    }
    else
    {
        if (!str.getIsNull())
        {
            unsigned uLen = getLength() + str.getLength() + 1U;
            char *pszTmp = new char[uLen];
            strcpy(pszTmp, getStr());
            strcat(pszTmp, str.getStr());

            if (getSize() >= uLen)
            {
                setStr(pszTmp);
                setLength(uLen - 1);
            }
            else
            {
                delete[] getStr();
                initString(pszTmp);
            }

            delete[] pszTmp;
        }
    }

    return *this;
}

inline void CMyString::initString(const char* str)
{
    if (str == nullptr)
    {
        setIsNull(true);
        setLength(0U);
        setSize(0U);
    }
    else
    {
        setIsNull(false);
        unsigned uLen = strlen(str) + 1U;
        setLength(uLen - 1U);
        setSize(uLen);
        getStr() = new char[uLen];
        setStr(str);
    }
}

CMyString& CMyString::myStrUpper()
{
    if (!getIsNull())
    {
        char *pchStr = getStr();
        while (*pchStr != '\0')
        {
            if (*pchStr >= 'a' && *pchStr <= 'z') { *pchStr -= 32; } } } return *this; } CMyString& CMyString::myStrLower() { if (!getIsNull()) { char *pchStr = getStr(); while (*pchStr != '\0') { if (*pchStr >= 'A' && *pchStr <= 'Z') { *pchStr += 32; } } } return *this; } inline void CMyString::myStrClear() { setIsNull(true); } inline const char* CMyString::myFindSubStr(CMyString& str) { if (str.getLength() > getLength())
    {
        return nullptr;
    }
    else if (getIsNull() || str.getIsNull())
    {
        if (getIsNull() && str.getIsNull())
        {
            return getStr();
        }
        else
        {
            return nullptr;
        }
    }
    else
    {
        //标记是否搜索成功
        const char *isSubStr = nullptr;
        //字符串
        const char *pNowstr = getStr();
        //需要被搜索的字符串
        const char *pFindStr = str.getStr();
        //调至字符串和被搜索的字符串末尾
        while (*pNowstr != '\0')
        {
            pNowstr++;
        }
        pNowstr--;

        while (*pFindStr != '\0')
        {
            pFindStr++;
        }
        pFindStr--;
        //记录一下被搜索的字符串的尾地址
        const char *pFindStrLastPointer = pFindStr;
        //当字符串为开始地址的时候结束
        do
        {
            //如果被搜索的字符串为开始位置
            if (pFindStr == str.getStr() - 1)
            {
                isSubStr = pNowstr + 1;
                break;
            }
            else if (*pNowstr != *pFindStr)
            {
                pNowstr--;
            }
            else//如果有相同的字符串的时候
            {
                do
                {
                    if (*pNowstr != *pFindStr)
                    {
                        pFindStr = pFindStrLastPointer; //如果还没到结束就不相等了,把字符设为尾巴
                        break;
                    }
                    else
                    {
                        pFindStr--;
                        pNowstr--;
                    }
                } while (pFindStr != str.getStr() - 1);//当被搜索的字符串为开始时表明相等

            }
        } while (pNowstr != getStr() - 1);

        //如果两个都结束表示查找的全匹配
        if (pNowstr == getStr() - 1 && pFindStr == str.getStr() - 1)
        {
            isSubStr = getStr();
        }

        return isSubStr;
    }
}

const char *CMyString::getBuff()
{
    if (getIsNull())
    {
        return nullptr;
    }
    else
    {
        return getStr();
    }
}

const char * CMyString::getSubStrPointer(CMyString & str)
{
    return myFindSubStr(str);
}

const int CMyString::myStrcmp(CMyString& str)
{
    if (getIsNull() || str.getIsNull())
    {
        if (getIsNull() && str.getIsNull())
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }
    return strcmp(getStr(), getStr());
}

const bool CMyString::checkIsPlalindrome()
{
    if (getLength() <= 2U)
    {
        return false;
    }

    const char *pStr = getStr();
    unsigned uI = 0;
    unsigned uJ = getLength() - 1U;
    while ((*(pStr + uI) == *(pStr + uJ)) && (uI <= uJ)) { uI++; uJ--; } if (uI > uJ)
    {
        return true;
    }
    else
    {
        return false;
    }
}
0 条评论
发表一条评论