c++要点

c++基础知识

  从一个基本的CMyString类讲起,分析了

    构造函数

    拷贝构造函数

    析构函数

    "="、"+="、"+"、左"++"、右"++"操作符重载

    "<<"输出流友元函数重载

  1、实现过程要关注内存泄露(析构)、非法输入值处理(“赋值重载”)、内存溢出异常处理(“赋值”重载)。

  2、操作符重载特别注意返回值类型和返回方式

 

  面向对象的三大特征:封装、继承和多态。多态特征将在工厂模式里强调。

class CMyString
{
public:
    CMyString(const char *pData = NULL)
    {
        /*
        构造函数
            作用:完成对象的初始化
            调用顺序:
                    a. 静态成员对象的构造函数。因为静态成员是与类直接相关的,在类内声明,在类的外部定义,并且只初始化一次。
                    b. 抽象基类的构造函数(按继承的顺序)
                    c. 虚拟基类的构造函数(按继承的顺序)
                    d. 非虚拟基类的构造函数(按继承的顺序)
                    e. 非静态成员对象的构造函数(按声明的顺序)
                    f. 调用类的构造函数。
        */
        if (pData == NULL)
        {
            m_pData = new char[1];
            m_pData[0] = '\0';
        }
        else
        {
            //字符串数组的拷贝拷贝方式
            int length = strlen(pData);
            m_pData = new char[length + 1];
            strcpy(m_pData, pData);
        }
    }

    CMyString(const CMyString& str)
    {
        /*
         *    拷贝构造函数
         *        1、深拷贝与浅拷贝
         *            当类成员变量为指向堆空间的指针时,需要采用深拷贝,防止两个对象之间的干扰
         *        2、深拷贝过程
         *            为类成员指针分配新的堆上空间
         *            执行内容拷贝
         *
         */
        int length = strlen(str.m_pData);
        m_pData = new char[strlen(str.m_pData) + 1];
        strcpy(m_pData, str.m_pData);
    }

    ~CMyString(void)
    {
        /*
         *    析构函数
         *        1、默认析构函数
         *        2、当类成员使用堆上空间时,需要自定义析构函数,防止内存泄露
         */
        delete [] m_pData;    
    }

    CMyString& operator=(const CMyString& str)
    {
        /*
         *    =操作符重载
         *        1、要点
         *            a. 返回类型声明为该类型的引用,并且在函数结束前返回对象自身的引用(*this)
         *            b. 传入参数为常量引用
         *            c. 拷贝时首先需要释放堆上空间,防止内存泄露
         *            d. 判断参数对象与当前对象是不是同一个对象
         *        2、重载:匹配同名函数的参数列表,返回值类型不在考虑范围
         *        3、成员函数参数列表隐含了this指针,指向当前对象
         */

        if (this == &str)
        {
            //判断参数对象与当前对象是不是同一个对象
            return *this;
        }

        //释放堆上空间,防止内存泄露
        delete [] m_pData;
        m_pData = NULL;

        int length = strlen(str.m_pData);
        m_pData = new char[length + 1]; //bug: 当内存溢出时,抛出异常,对象失效
        strcpy(m_pData, str.m_pData);

        //返回对象自身的引用
        return *this;
    }

    CMyString& operator += (CMyString& rhs)
    {
        /*
         *    +=操作符重载
         *        1、返回当前类型的引用,函数结束时返回当前实例的引用*this
         */
        CMyString temp; //定义临时变量,防止内存溢出而抛出异常

        int length;
        length = strlen(m_pData) + strlen(rhs.m_pData);

        temp.m_pData = new char[length + 1];
        strcpy(temp.m_pData, m_pData);
        strcat(temp.m_pData, rhs.m_pData); //字符串的拼接
        
        char *pTemp = m_pData;
        m_pData = temp.m_pData;
        temp.m_pData = pTemp; //将当前实例的堆空间赋值给临时变量,在函数退出时析构

        return *this;
    }

    CMyString operator + (CMyString& rhs)
    {
        /*
         * + 操作符重载
         *         返回右值,也即将临时对象返回
         *         返回过程:
         *             a. 调用拷贝构造函数,生成匿名临时对象,用于返回
         *             b. 析构局部对象
         */

        CMyString ret;
        int length;

        length = strlen(m_pData) + strlen(rhs.m_pData);
        ret.m_pData = new char[length + 1];
        strcpy(ret.m_pData, m_pData);
        strcat(ret.m_pData, rhs.m_pData);
        
        return ret;
    }

    CMyString& operator ++()
    {
        /*
         *    前加
         *        返回引用,作为左值
         */
        int length;
        char *pTemp = m_pData;

        length = strlen(m_pData) * 2;

        m_pData = new char[length + 1];
        strcpy(m_pData, pTemp);
        strcat(m_pData, pTemp);

        delete [] pTemp;

        return *this;
    }

    CMyString operator ++(int rhs)
    {
        /*
         *    后加
         *        形参:标识重载函数
         *        返回值:返回对象,作为右值
         */
        CMyString ret = *this;

        int length;
        
        char *pTemp = m_pData;

        length = strlen(m_pData) * 2;

        m_pData = new char[length + 1];
        strcpy(m_pData, pTemp);
        strcat(m_pData, pTemp);
        
        delete [] pTemp;

        return ret;
    }

    //友元
    //    输出流重载
    //    作用:扩展外部函数的访问权限
    friend ostream& operator<< (ostream& os, const CMyString& str);

private:
    char *m_pData;
};

//友元函数的实现
ostream& operator<< (ostream& os, const CMyString& str)
{
    os << str.m_pData;
    return os;
}

 

    

posted on 2014-07-09 20:53  zjgtan  阅读(384)  评论(0编辑  收藏  举报

导航