0. 温习

0.1 虚继承

当咱们应用多继承的时候,子类的多个父类有同名成员,拜访的时候,会呈现二义性class CA{  public:        int m_a;};class CB{  public:int m_a;};class CTest:public CA,public CB{};int main(){CTest obj;obj.m_a = 10;return 0;}


解决形式1:能够应用类的作用域拜访具体某一个父类的成员

解决形式2:给CA和CB形象出一个独特的父类,而后应用虚继承

class CBase{public:    int m_a;};class CA:virtual public CBase{public:    //int m_a;};class CB:virtual public CBase{public:    //int m_a;};class CTest :public CA, public CB{};int main(){    CTest obj;    obj.m_a = 20;    obj.CA::m_a = 10;    obj.CB::m_a = 20;    return 0;}

如果类B虚继承自类A,此时类A就是虚基类

0.2 虚函数与多态

当咱们应用父类指针指向子类对象,调用虚函数,优先调用子类的虚函数。子类如果没有实现这个虚函数,就调用父类的。
虚函数是多态机制,属于动静联编。
virtual void fun() =0 ; 这个叫做纯虚函数。只是提供了接口,没有提供具体实现,实现由子类来实现。
抽象类:蕴含纯虚函数的类,也叫做抽象类。如果子类没有实现父类中的纯虚函数,子类也是抽象类。
抽象类的特点:不能定义对象

class Tuxing{public:    virtual int ClacArea() = 0;};class Sanjiaoxing:public Tuxing{public:    int ClacArea()    {        return m_nBottom * m_nHeight / 2;    }private:    int m_nBottom;    int m_nHeight;};class CZhengfangxing :public Tuxing{    int ClacArea()    {        //..        return m_nLenth * m_nLenth;    }private:    int m_nLenth;};class CCircle:public Tuxing{};int main(){    CCircle obj;     CZhengfangxing obj2;    return 0;}

重载,重定义,虚函数定义

重载: 雷同作用域 函数名雷同 参数不同 调用的时候依据传参的不同,编译器主动调用相应的函数
重定义:继承关系中 函数名雷同 参数能够雷同也能够不雷同 子类对象默认调用本人的
虚函数:继承关系中 函数名雷同 参数雷同 须要加上virtual 应用特点:父类指针指向子类对象,调用虚函数,优先调用子类的

0.3 模板

0.3.1函数模板

template <typename M,typename N,typename L>void Fun(M a, N b, L c, int nLenth){}int main(){    Fun(1, 2.5, 'c', 100);    return 0;}

模板的特化:
不能应用通用算法解决一些数据类型,能够为其独自实现算法。这个叫做特化

template <>void Fun(int a, int b, double c, int nLenth){}

0.3.2 类模板

咱们应用C语言的数组,它的长度只能是一个常量,不能动静扩大。应用起来不太不便。对于一些惯例的数组操作,都须要本人去实现。没有面向对象的反对,咱们实现一个动静数组,反对以下性能:
1.反对动静增长
2.反对任意数据类型
3.反对惯例的数组操作
(增 删 改 查)

#pragma once//先实现一个存储int类型的数组,元素如果最多100个template<typename T>class CMyArr{public:    CMyArr(int nMax = 3);    //减少一个数据    bool Insert(T nData, int nLoc);    //删除一个数据    bool DeleteEle(int nLoc);    bool ModifyByLoc(T nData, int nLoc);    bool GetEleByLoc(int nLoc, T& Ele);    //获取以后元素个数    int GetLenth();    bool sort();private:    T* m_buf;    int m_nLenth;    int m_nMax;};template<typename T>CMyArr<T>::CMyArr(int nMax) :m_buf{ 0 }, m_nLenth(0), m_nMax(nMax){    m_buf = new T[nMax]{ 0 };}//减少一个数据template<typename T>bool CMyArr<T>::Insert(T nData, int nLoc){    //1. 检测传入的地位,是否正确    if (nLoc<0 || nLoc>m_nLenth)    {        return false;    }    //2. 是否缓冲区曾经满了    if (m_nLenth == m_nMax)    {        //如果缓冲区满了,那么就能够申请更大的空间,而后去存储        T* pTemp = new T[m_nMax * 2]{ 0 };        //将老缓冲区中的数据拷贝到新申请的缓冲区        for (int i = 0; i < m_nMax; i++)        {            pTemp[i] = m_buf[i];        }        //开释原来的缓冲区        delete[]m_buf;        m_buf = pTemp;        m_nMax *= 2;    }    //3. 增加数据的地位,在结尾,间接增加    if (m_nLenth == nLoc)    {        m_buf[nLoc] = nData;        m_nLenth++;        return true;    }    //4. 增加数据的地位,在两头,须要挪动数据,再增加    for (int i = m_nLenth - 1; i >= nLoc; i--)    {        m_buf[i + 1] = m_buf[i];    }    //曾经挪动完数据了,增加数据    m_buf[nLoc] = nData;    m_nLenth++;    return true;}//删除一个数据template<typename T>bool CMyArr<T>::DeleteEle(int nLoc){    //1. 检测地位是否正确    if (nLoc < 0 || nLoc >= m_nLenth)    {        return false;    }    //2. 删除的是结尾,不须要挪动    if (nLoc == m_nLenth - 1)    {        m_nLenth--;        return true;    }    //3. 删除的是两头,就须要挪动    for (int i = nLoc; i < m_nLenth - 1; i++)    {        m_buf[i] = m_buf[i + 1];    }    m_nLenth--;    return true;}template<typename T>bool CMyArr<T>::ModifyByLoc(T nData, int nLoc){    //1. 检测地位是否正确    if (nLoc < 0 || nLoc >= m_nLenth)    {        return false;    }    //2. 地位没有问题,间接赋值    m_buf[nLoc] = nData;    return true;}template<typename T>bool CMyArr<T>::GetEleByLoc(int nLoc, T& Ele){    //1. 检测地位是否正确    if (nLoc < 0 || nLoc >= m_nLenth)    {        return false;    }    //2. 地位没有问题,间接赋值    Ele = m_buf[nLoc];    return true;}//获取以后元素个数template<typename T>int CMyArr<T>::GetLenth(){    return m_nLenth;}template<typename T>bool CMyArr<T>::sort(){    for (int j = 1; j < m_nLenth; j++)    {        for (int i = 0; i < m_nLenth - j; i++)        {            if (m_buf[i] > m_buf[i + 1])            {                T nTemp = m_buf[i];                m_buf[i] = m_buf[i + 1];                m_buf[i + 1] = nTemp;            }        }    }    return true;}

具体的应用:

#include <iostream>#include "MyArr.h"int main(){    CMyArr<int> obj;    obj.Insert(10, 0);    obj.Insert(20, 0);    obj.Insert(30, 0);    obj.Insert(100, 1);    obj.Insert(200, 2);    obj.DeleteEle(1);    obj.ModifyByLoc(500, 1);    obj.sort();    for (int i = 0; i < obj.GetLenth(); i++)    {        int nEle = 0;        obj.GetEleByLoc(i, nEle);        std::cout << nEle << "  ";    }    CMyArr<char> obj2;    obj2.Insert('a', 0);    obj2.Insert('b', 1);    obj2.Insert('c', 0);    obj2.Insert('d', 1);    obj2.Insert('e', 2);    obj2.Insert('f', 1);    for (int i = 0; i < obj2.GetLenth(); i++)    {        char nEle = 0;        obj2.GetEleByLoc(i, nEle);        std::cout << nEle << "  ";    }    obj2.sort();    std::cout << std::endl;    for (int i = 0; i < obj2.GetLenth(); i++)    {        char nEle = 0;        obj2.GetEleByLoc(i, nEle);        std::cout << nEle << "  ";    }    return 0;}

STL -vector

1.1 vertor的根本应用

#include <iostream>#include <vector>#include <algorithm>using std::vector;int main(){    vector<int> obj;    //1. 减少    //push_back 在结尾增加    //insert    在两头增加    obj.push_back(1);    obj.push_back(2);    obj.push_back(3);    obj.push_back(4);    obj.push_back(5);    obj.push_back(6);    //vector中应用迭代器来标识地位    //咱们能够暂且认为迭代器是一个指针    //能够有 +   -   *的操作    //获取起始地位的迭代器    vector<int>::iterator it1 = obj.begin();    obj.insert(it1+2, 100);    //2. 删除    //pop_back  删除结尾    //erase     删除两头    //clear     全副删掉    obj.pop_back();    vector<int>::iterator it2 = obj.begin();    obj.erase(it2+3);    //3. 查问    //反对下标运算    //size  获取元素个数    std::cout << obj[2];    std::cout << obj.size();    //4. 批改    obj[2] = 10;    std::cout << std::endl;    //5. 遍历    //第一种遍历形式    for (int i = 0; i < obj.size(); i++)    {        std::cout << obj[i]<<"  ";    }    std::cout << std::endl;    //第二种遍历形式    //obj.end()是结尾的迭代器,是最初一个元素的前面    vector<int>::iterator it3 = obj.begin();    for (; it3 != obj.end(); it3++)    {        std::cout << *it3 << "  ";    }    std::cout << std::endl;    //6. 排序    std::sort(obj.begin(), obj.end());    for (int i = 0; i < obj.size(); i++)    {        std::cout << obj[i] << "  ";    }    std::cout << std::endl;    return 0;}

1.2 应用vector实现一个密码本

#include <iostream>#include <vector>using std::vector;class CPassWordInfo{public:    CPassWordInfo(const char* szWeb = nullptr,        const char* szUserName = nullptr,        const char* szPwd=nullptr)    {        strcpy_s(m_szWeb, 20, szWeb);        strcpy_s(m_szUserName, 20, szUserName);        strcpy_s(m_szPwd, 20, szPwd);    }    char* GetWeb()    {        return m_szWeb;    }    char* GetUserName()    {        return m_szUserName;    }    char* GetPwd()    {        return m_szPwd;    }    void SetWeb(const char* szWeb = nullptr)    {        strcpy_s(m_szWeb, 20, szWeb);    }    void SetUserName(const char* szUserName)    {        strcpy_s(m_szUserName, 20, szUserName);    }    void SetPwd(const char* szPwd = nullptr)    {        strcpy_s(m_szPwd, 20, szPwd);    }    bool Veryrify()    {    }private:    char m_szWeb[20];    char m_szUserName[20];    char m_szPwd[20];};vector<CPassWordInfo> g_PwdBook;int main(){    //1. 用户输出要进行的操作    int nSelect = 0;    while (true)    {        system("cls");        std::cout << "减少" << std::endl;        std::cout << "删除" << std::endl;        std::cout << "查问所有" << std::endl;        std::cout << "批改" << std::endl;        std::cout << "输出你的抉择(1~4):" << std::endl;        std::cin >> nSelect;        switch (nSelect)        {        case 1://减少        {            char szWebSite[20] = { 0 };            char szUserName[20] = { 0 };            char szPwd[20] = { 0 };            //1. 输出站点的信息            std::cout << "站点:" << std::endl;            std::cin >> szWebSite;            std::cout << "账号:" << std::endl;            std::cin >> szUserName;            std::cout << "明码:" << std::endl;            std::cin >> szPwd;            //2. 构建一个对象,存储到vector            CPassWordInfo obj(szWebSite, szUserName, szPwd);            g_PwdBook.push_back(obj);            break;        }        case 2://删除        {            int nDelete = 0;            std::cout << "请输出你要删除的序号:" << std::endl;            std::cin >> nDelete;            //删除的时候,须要传递迭代器            vector<CPassWordInfo>::iterator it = g_PwdBook.begin();            g_PwdBook.erase(it+nDelete);            break;        }        case 3://查问所有        {            vector<CPassWordInfo>::iterator it = g_PwdBook.begin();            for (; it != g_PwdBook.end(); it++)            {                std::cout << "站点:"<<(*it).GetWeb()<<"  ";                std::cout << "用户名:" << (*it).GetUserName()<<"  ";                std::cout << "明码:" << (*it).GetPwd()<<std::endl;            }            break;        }        case 4:        {            int nModify = 0;            //1. 输出要批改的地位            std::cout << "要批改几号:" ;            std::cin >> nModify;            //2. 输出具体数据            char szWebSite[20] = { 0 };            char szUserName[20] = { 0 };            char szPwd[20] = { 0 };            //3. 输出站点的信息            std::cout << "站点:" << std::endl;            std::cin >> szWebSite;            std::cout << "账号:" << std::endl;            std::cin >> szUserName;            std::cout << "明码:" << std::endl;            std::cin >> szPwd;            //4. 进行批改            g_PwdBook[nModify].SetWeb(szWebSite);            g_PwdBook[nModify].SetUserName(szUserName);            g_PwdBook[nModify].SetPwd(szPwd);            //5. 校验明码            g_PwdBook[nModify].Veryrify();        }        default:            break;        }        system("pause");    }}