29_常成员初始化列表静态函数

常成员函数

  1. 常成员函数,在成员函数后面加上const
  2. 作用,防止自己修改数据成员
  3. const修饰的指针对象不能调用成员函数,只能调用常成员函数
  4. static_cast转换类型,有风险不让转

初始化列表

  1. const修饰的数据成员在C11之前不能直接初始化
  2. 初始化列表,构造函数外面加冒号 成员对象(值),以逗号分隔。可以初始化const修饰的数据成员与指明成员对象的构造参数
  3. 初始化列表的顺序,不影响顺序
  4. 数据成员对象比初始化列表先初始化,按照定义顺序构造
  5. 先析构自己,再反顺序析构成员对象

静态数据成员

  1. errrno接受错误
  2. 替代了C语言的全局变量
  3. 不占对象数据空间,在类外初始化一次,全局数据区,整个类对象共享一份
  4. 非静态成员函数,可以访问静态数据成员
  5. 静态成员函数无this指针
  6. 静态成员函数,不可以访问非静态数据成员
  7. 无名对象

作业

1.设计一个类,只能产生一个对象
2.实现一个类,定义的对象只在堆上
3.实现一个类,定义的对象只能存在栈上
4.实现一个类,定义出的对象不能在堆上

 //1-4.cpp
//1.设计一个类,只能产生一个对象
class ClassOnly
{
public:
    static ClassOnly& GetInstance()
    {
        static ClassOnly obj;
        return obj;
    }
private:
    ClassOnly(){};
    ClassOnly(const ClassOnly&);
    ClassOnly& operator = (const ClassOnly&);
};

ClassOnly &test = ClassOnly::GetInstance();

//2.实现一个类,定义的对象只在堆上
class HeapOnly
{
public:
    static HeapOnly* creatHeapOnly()
    {
        return new HeapOnly;
    }
private:
    HeapOnly() {};
    HeapOnly(const HeapOnly& h) {};
};

//3.实现一个类,定义的对象只能存在栈上
class  StackOnly
{
private:
    void * operator  new (size_t  t) {}      // 注意函数的第一个参数和返回值都是固定的
    void  operator  delete (void * ptr) {}  // 重载了new就需要重载delete
public:
    StackOnly() {}
    ~StackOnly() {}
};

//4.实现一个类,定义出的对象不能在堆上
class  StackOnlyTWO
{
private:
    void * operator  new (size_t  t) {}      // 注意函数的第一个参数和返回值都是固定的
    void  operator  delete (void * ptr) {}  // 重载了new就需要重载delete
public:
    StackOnlyTWO() {}
    ~StackOnlyTWO() {}
};

#include "CMyString.h"
#include 

void main()
{
    ClassOnly &a = test.GetInstance();
    a.GetInstance();
    bool b = false;
    char ch = 'f';
    double d = 2.323456745674;
    float f = 1.3456f;
    int i = 33212;
    long l = 12345L;
    short s = 99;
    const char *pcStr = "Hello World";
    cout << CMyString::ValueOf(b) << endl;
    cout << CMyString::ValueOf(ch) << endl;
    cout << CMyString::ValueOf(d) << endl;
    cout << CMyString::ValueOf(f) << endl;
    cout << CMyString::ValueOf(i) << endl;
    cout << CMyString::ValueOf(l) << endl;
    cout << CMyString::ValueOf(s) << endl;
    cout << CMyString::ValueOf(pcStr) << endl;
}

5.完善string类,加入常成员函数,增加以下静态方法
static string ValueOf(boolean b) //true ==> "true"
static string ValueOf(char c) //a ==> "a"
static string ValueOf(double d) //3.5 ==> "3.5"
static string ValueOf(float f) //4.5f ==> "4.5"
static string ValueOf(int i) //123 ==> "123"
static string ValueOf(long i) //123 ==> "123"
static string ValueOf(short i) //123 ==> "123"
static string ValueOf(const char* data) //char[] = "123" ==> string "123"
static string CopyValueOf(const char* data, int offset, int count) //char[] = "123" ==> string "123"
static string Format(String format, ...) //("%d", 123) ==> string "123"

 //CMyString.h
#pragma once
#include 
#include 

using namespace std;

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
    static string ValueOf(bool b);  //true ==> "true"
    static string ValueOf(char c);     //a ==> "a" 
    static string ValueOf(double d);   //3.5 ==>   "3.5" 
    static string ValueOf(float f);    //4.5f ==> "4.5" 
    static string ValueOf(int i);     //123 ==> "123" 
    static string ValueOf(long i);    //123 ==> "123" 
    static string ValueOf(short i);    //123 ==> "123" 
    static string ValueOf(const char* data); //char[] = "123" ==> string "123" 
    static string CopyValueOf(const char* data, int offset, int count); //char[] = "123" ==> string "123" 
    static string Format(CMyString format, ...);  //("%d", 123) ==> string "123" 
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); //初始化字符串
    static void clearFormatHeap(); //清理格式化的堆空间
private:
    char *m_pStr; //指向字符串的数组
    unsigned m_uLenth;   //字符串的实际使用长度
    unsigned m_uSize;    //字符串的实际占用的内存大小
    bool m_bIsNull; //是否为空标记
    static char *m_pFormatStr;
};
 //CMyString.cpp
#include "CMyString.h"


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);
    }
}

void CMyString::clearFormatHeap()
{
    if (m_pFormatStr != nullptr)
    {
        delete[] m_pFormatStr;
        m_pFormatStr = nullptr;
    }
}

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;
    }
}

string CMyString::ValueOf(bool b)
{
    clearFormatHeap();
    char *szS = new char[6];
    m_pFormatStr = szS;
    if (b == true)
    {   
        strcpy(szS, "true");
    }
    else
    {
        strcpy(szS, "false");
    }

    return m_pFormatStr;
}

string CMyString::ValueOf(char c)
{
    clearFormatHeap();
    char *szS = new char[2];
    m_pFormatStr = szS;
    sprintf(szS, "%c", c);
    return m_pFormatStr;
}

string CMyString::ValueOf(double d)
{
    clearFormatHeap();
    char *szS = new char[100];
    m_pFormatStr = szS;
    sprintf(szS, "%E", d);
    return m_pFormatStr;
}

string CMyString::ValueOf(float f)    //4.5f ==> "4.5"
{
    clearFormatHeap();
    char *szS = new char[100];
    m_pFormatStr = szS;
    sprintf(szS, "%f", f);
    return m_pFormatStr;
}

string CMyString::ValueOf(int i)     //123 ==> "123" 
{
    clearFormatHeap();
    char *szS = new char[100];
    m_pFormatStr = szS;
    sprintf(szS, "%d", i);
    return m_pFormatStr;
}

string CMyString::ValueOf(long i)    //123 ==> "123" 
{
    clearFormatHeap();
    char *szS = new char[100];
    m_pFormatStr = szS;
    sprintf(szS, "%ld", i);
    return m_pFormatStr;
}

string CMyString::ValueOf(short i)    //123 ==> "123" 
{
    clearFormatHeap();
    char *szS = new char[100];
    m_pFormatStr = szS;
    sprintf(szS, "%d", i);
    return m_pFormatStr;
}

string CMyString::ValueOf(const char* data) //char[] = "123" ==> string CMyStrig::"123" 
{
    clearFormatHeap();
    int lenth = strlen(data) + 1;
    char *szS = new char[lenth];
    m_pFormatStr = szS;
    sprintf(szS, "%s", data);
    return m_pFormatStr;
}


/*
string CMyString::CopyValueOf(const char* data, int offset, int count) //char[] = "123" ==> string CMyStrig::"123" 
{

}

string CMyString::Format(CMyString format, ...)  //("%d", 123) ==> string CMyStrig::"123" 
{
}
*/

char *CMyString::m_pFormatStr = nullptr;
0 条评论
发表一条评论