• 传智播客C++视频学习笔记(3)


    #include<iostream>
    
    using namespace std;
    
    //内存分区模型
    //代码区,存放二进制代码,由操作系统进行管理
    //全局区,存放全局变量、静态变量、常量(字符串常量和const修饰的全局常量)
    //栈区,存放函数参数值、局部变量等,由编译器自动分配释放
    //堆区,由程序员分配和释放,若程序员不,程序结束时由操作系统回收
    //内存四区意义,不同区域存放的数据赋予不同的生命周期,给我们更大的灵活编程
    
    //程序运行前:代码区,全局区
    //程序运行后:栈区,堆区
    
    //全局变量
    int g_a = 10;
    int g_b = 10;
    
    //const修饰的全局常量
    const int c_g_a = 10;
    const int c_g_b = 10;
    
    int main()
    {
        //局部变量
        int a = 10;
        int b = 10;
        cout << "局部变量地址为 " << (int)&a << endl;
        cout << "局部变量地址为 " << (int)&b << endl;
        cout << "全局变量地址为 " << (int)&g_a << endl;
        cout << "全局变量地址为 " << (int)&g_b << endl;
    
        //静态变量
        static int s_a = 10;
        static int s_b = 10;
        cout << "静态变量地址为 " << (int)&s_a << endl;
        cout << "静态变量地址为 " << (int)&s_b << endl;
    
        //字符串常量
        string s1 = "s1";
        string s2 = "s2";
        cout << "字符串常量地址为 " << (int)&s1 << endl;
        cout << "字符串常量地址为 " << (int) & "s2" << endl;
    
        //const修饰的全局常量
        cout << "const修饰的全局常量 " << (int)&c_g_a << endl;
        cout << "const修饰的全局常量 " << (int)&c_g_b << endl;
    
        //const修饰的局部常量
        const int c_l_a = 10;
        const int c_l_b = 10;
        cout << "const修饰的局部常量 " << (int)&c_l_a << endl;
        cout << "const修饰的局部常量 " << (int)&c_l_b << endl;
    
        system("pause");
    
        return 0;
    }
    内存分区模型

    #include<iostream>
    
    using namespace std;
    
    int* func(int b) //形参数据也会存放在栈区
    {
        int a = 10;
        return &a; //不要返回局部变量的地址,局部变量存放在栈区,栈区开辟的数据由编译器自动释放
    }
    
    int main()
    {
        int* p = func(1);
    
        cout << *p << endl; //第一次打印正确,是因为编译器做了保留
        cout << *p << endl; //第二次打印错误
    
        system("pause");
    
        return 0;
    }
    栈区
    #include<iostream>
    
    using namespace std;
    
    int* func()
    {
        int* p = new int(10); //利用new关键字可以将数据开辟到堆区
        return p;             //指针本质上也是局部变量,放在栈上,但指针保存的数据是放在堆区
    }                         //栈:int* p 0x0011
                              //堆:0x0011 10
    int main()
    {
        int* p = func();
    
        cout << *p << endl;
        cout << *p << endl;
    
        system("pause");
    
        return 0;
    }
    堆区
    #include<iostream>
    
    using namespace std;
    
    int* func()
    {
        int* p = new int(10);
        return p;
    }
    
    int main()
    {
        int* p = func();
    
        cout << *p << endl;
        cout << *p << endl;
    
        delete p;
    
        //cout << *p << endl; //报错
        cout << "------------------------------------" << endl;
    
    
        //堆区开辟数组
    
        int* arr = new int[10];
    
        for (int i = 0; i < 10; i++)
        {
            arr[i] = i + 100;
        }
    
        for (int i = 0; i < 10; i++)
        {
            cout << arr[i] << endl;
        }
    
        delete[] arr;
    
        system("pause");
    
        return 0;
    }
    new操作符
    #include<iostream>
    
    using namespace std;
    
    int main()
    {
        int a = 10;
        int& b = a; //给变量起别名
    
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
    
        b = 100;
    
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
    
        system("pause");
    
        return 0;
    }
    引用的基本使用
    #include<iostream>
    
    using namespace std;
    
    int main()
    {
    
    
    
        int a = 10;
        int b = 20;
    
        //引用必须初始化
        //int& c;
    
        //引用初始化后不可以改变
        int& c = a;
        c = b; //这是赋值操作
    
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
        cout << "c = " << c << endl;
    
        system("pause");
    
        return 0;
    }
    引用注意事项
    #include<iostream>
    
    using namespace std;
    
    //值传递
    void mySwap01(int a, int b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    
    //地址传递 
    void mySwap02(int* p1, int* p2)
    {
        int temp = *p1;
        *p1 = *p2;
        *p2 = temp;
    }
    
    //引用传递
    void mySwap03(int& a, int& b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    
    int main()
    {
        int a = 10;
        int b = 20;
    
        //mySwap01(a, b);
    
        //mySwap02(&a, &b);
    
        mySwap03(a, b);
    
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
    
        system("pause");
    
        return 0;
    }
    引用做函数参数
    #include<iostream>
    
    using namespace std;
    
    //返回局部变量引用
    int& test01()
    {
        int a = 10;
        return a;
    }
    
    //返回静态变量引用
    int& test02()
    {
        static int a = 100;
        return a;
    }
    
    
    int main()
    {
        //不要返回局部变量引用
        int& ref = test01();
        cout << "ref = " << ref << endl;
        cout << "ref = " << ref << endl;
    
        //返回静态变量引用
        int& ref2 = test02();
        cout << "ref2 = " << ref2 << endl;
        cout << "ref2 = " << ref2 << endl;
    
        //函数调用作为左值,必须返回引用
        test02() = 1000;
        cout << "ref2 = " << ref2 << endl;
        cout << "ref2 = " << ref2 << endl;
    
        system("pause");
    
        return 0;
    }
    引用做函数返回值
    #include<iostream>
    
    using namespace std;
    
    void func(int& ref)
    {
        ref = 100;
    }
    
    int main()
    {
        int a = 10;
    
        //引用本质是在C++内部实现一个指针常量
        //指针常量,指针指向不可以修改,即引用不可以修改
        //int* const ref = &a;
        int& ref = a;
    
        //*ref = 20;
        ref = 20;
    
        cout << "a = " << a << endl;
        cout << "ref = " << ref << endl;
    
        func(a);
    
        cout << "a = " << a << endl;
        cout << "ref = " << ref << endl;
    
        system("pause");
    
        return 0;
    }
    引用的本质
    #include<iostream>
    
    using namespace std;
    
    //常量引用通常用来修饰形参
    void showValue(const int& v)
    {
        //v += 10;
        cout << "v = " << v << endl;
    }
    
    int main()
    {
        //常量引用主要用来修饰形参,防止误操作,即防止形参改变实参
    
        //错误,需要加一个const修饰
        //int& ref = 10;
    
        //int temp = 10; const int& ref = temp;
        const int& ref = 10;
    
        //ref = 100; //不可以修改
    
        //函数中利用常量引用防止误操作修改实参
        int a = 10;
        showValue(a);
    
        system("pause");
    
        return 0;
    }
    常量引用
    #include<iostream>
    
    using namespace std;
    
    //函数参数某个位置有默认值,那么从这个位置往后,从左到右,必须都要有默认值
    int func(int a, int b = 10, int c = 20)
    {
        return a + b + c;
    }
    
    //如果函数声明有默认值,函数实现就不能有默认值,二者冲突
    ///函数声明
    int func2(int a = 10, int b = 20);
    //函数实现
    int func2(int a, int b)
    {
        return a + b;
    }
    
    int main()
    {
        cout << "return = " << func(20, 20) << endl; //60
    
        cout << "return = " << func2(20, 20) << endl; //40
    
        system("pause");
    
        return 0;
    }
    函数默认参数
    #include<iostream>
    
    using namespace std;
    
    //函数占位参数,也可以有默认值
    void func(int a, int)
    {
        cout << "this is func" << endl;
    }
    
    int main()
    {
        func(10, 10);
    
        system("pause");
    
        return 0;
    }
    函数占位参数
    #include<iostream>
    
    using namespace std;
    
    //函数重载条件:
    //同一作用域下
    //函数名称相同
    //函数参数类型不同、个数不同、顺序不同
    //注:函数返回值不同不可以作为函数重载的满足条件
    
    void func()
    {
        cout << "func()调用" << endl;
    }
    
    void func(int a)
    {
        cout << "func(int a)调用" << endl;
    }
    
    void func(double d)
    {
        cout << "func(double d)调用" << endl;
    }
    
    void func(int a, double d)
    {
        cout << "func(int a, double d)调用" << endl;
    }
    
    void func(double d, int a)
    {
        cout << "func(double d, int a)调用" << endl;
    }
    
    int main()
    {
        func();
        func(1);
        func(1.1);
        func(1, 1.1);
        func(1.1, 1);
    
        system("pause");
    
        return 0;
    }
    函数重载概述
    #include<iostream>
    
    using namespace std;
    
    //引用作为重载条件
    void func(int& a)
    {
        cout << "func(int& a)调用" << endl;
    }
    void func(const int& a)
    {
        cout << "func(const int& a)调用" << endl;
    }
    
    //函数重载碰到函数默认参数
    void func2(int a, int b = 10)
    {
        cout << "func2(int a, int b = 10)调用" << endl;
    }
    void func2(int a)
    {
        cout << "func2(int a)调用" << endl;
    }
    
    int main()
    {
        int a = 10;
        func(a); //调用无const
        func(10); //调用有const
    
        func2(100, 100); //此处填一个参数会产生歧义
    
        system("pause");
    
        return 0;
    }
    函数重载注意事项
    #include<iostream>
    
    using namespace std;
    
    //类和对象
    //面向对象三大特征:封装、继承、多态
    //万物皆对象,对象有属性和行为
    //车类,车
    ////设计一个圆类求其周长
    const double PI = 3.14;
    class Circle
    {
    public:
    
        int r;
    
        double zhouChang()
        {
            return 2 * PI * r;
        }
    };
    
    int main()
    {
        Circle c;
        c.r = 10;
        cout << "圆的周长 = " << c.zhouChang() << endl;
    
        system("pause");
    
        return 0;
    }
    封装意义(1)
    #include<iostream>
    
    using namespace std;
    
    class Student
    {
    public:
    
        string m_name;
        int m_id;
    
        void setName(string name)
        {
            m_name = name;
        }
    
        void setId(int id)
        {
            m_id = id;
        }
    
        void showStudent()
        {
            cout << "name = " << m_name << "   " << "id = " << m_id << endl;
        }
    };
    
    int main()
    {
        Student s;
        s.m_name = "张三";
        s.m_id = 100;
        //s.setName("李四");
        s.showStudent();
    
        system("pause");
    
        return 0;
    }
    学生类示例
    #include<iostream>
    
    using namespace std;
    
    //public 公共权限,类内类外均可以访问
    //protected 保护权限,类内可以访问类外不可以访问 
    //private 私有权限,类内可以访问类外不可以访问 
    
    class Preson
    {
    public:
        string m_name;
    
    protected:
        string m_car;
    
    private:
        int m_passWord;
    };
    
    int main()
    {
        Preson p;
        p.m_name = "张三";
        //p.m_car;
        //p.m_passWord;
    
        system("pause");
    
        return 0;
    }
    封装意义(2)
    #include<iostream>
    
    using namespace std;
    
    class C1
    {
        //默认为私有权限
        int m_c1;
    };
    
    struct C2
    {
        //默认为公共权限
        int m_c2;
    };
    
    int main()
    {
    
        C1 c1;
        //c1.m_c1;
    
        C2 c2;
        c2.m_c2 = 1000;
    
        system("pause");
    
        return 0;
    }
    class与struct区别
    #include<iostream>
    
    using namespace std;
    
    class Preson
    {
    private:
        string m_name;
    
        int m_age;
    
        string m_lover;
    
    public:
        void setName(string name)
        {
            m_name = name;
        }
    
        string getName()
        {
            return m_name;
        }
    
        void setAge(int age)
        {
            if (age < 0 || age > 150)
            {
                cout << "你是妖精吧" << endl;
            }
            m_age = age;
        }
    
        void setLover(string lover)
        {
            m_lover = lover;
        }
    
        string getLover()
        {
            return m_lover;
        }
    };
    
    int main()
    {
        Preson p;
        p.setName("张三");
        cout << "m_name = " << p.getName() << endl;
        p.setAge(151);
        p.setLover("波多野结衣");
        cout << "m_lover = " << p.getLover() << endl;
    
        system("pause");
    
        return 0;
    }
    成员属性设置为私有
    #include<iostream>
    
    using namespace std;
    
    #include "point.h"
    #include "circle.h"
    
    //判断点和圆关系的全局函数
    void isInCircle(Circle& c, Point& p)
    {
        //两点之间距离^2
        int ppDistance =
            (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +
            (c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
    
        //半径^2
        int rDistance = c.getR() * c.getR();
    
        //判断
        if (ppDistance == rDistance)
        {
            cout << "点在圆上" << endl;
        }
        else if (ppDistance > rDistance)
        {
            cout << "点在圆外" << endl;
        }
        else
        {
            cout << "点在圆内" << endl;
        }
    }
    
    int main()
    {
        //设置圆,半径为10,圆心坐标为(10,0)
        Circle c;
        c.setR(10);
        Point center;
        center.setX(10);
        center.setY(0);
        c.setCenter(center);
    
        //设置点
        Point p;
        p.setX(10);
        p.setY(11);
    
        //判断
        isInCircle(c, p);
    
        system("pause");
    
        return 0;
    }
    判断点和圆的位置关系
    #pragma once
    
    #include <iostream>
    using namespace std;
    
    class Point
    {
    private:
        //坐标X
        int m_x;
        //坐标Y
        int m_y;
    public:
        //设置X
        void setX(int x);
        //获取X
        int getX();
        //设置Y
        void setY(int y);
        //获取Y
        int getY();
    };
    point.h
    #include "point.h"
    
    //设置X
    void Point::setX(int x)
    {
        m_x = x;
    }
    
    //获取X
    int Point::getX()
    {
        return m_x;
    }
    
    //设置Y
    void Point::setY(int y)
    {
        m_y = y;
    }
    
    //获取Y
    int Point::getY()
    {
        return m_y;
    }
    point.cpp
    #pragma once
    
    #include <iostream>
    using namespace std;
    
    #include "point.h"
    
    class Circle
    {
    private:
        //半径
        int m_r;
        //圆心,类中有类
        Point m_center;
    public:
        //设置半径
        void setR(int r);
        //获取半径
        int getR();
        //设置圆心
        void setCenter(Point center);
        //获取圆心
        Point getCenter();
    };
    circle.h
    #include "circle.h"
    
    //设置半径
    void Circle::setR(int r)
    {
        m_r = r;
    }
    
    //获取半径
    int Circle::getR()
    {
        return m_r;
    }
    
    //设置圆心
    void Circle::setCenter(Point center)
    {
        m_center = center;
    }
    
    //获取圆心
    Point Circle::getCenter()
    {
        return m_center;
    }
    circle.cpp
    #include <iostream>
    
    using namespace std;
    
    //构造函数:创建对象时为对象成员属性赋值,由编译器自动调用
    
    //析构函数:对象销毁前系统自动调用
    
    //构造函数语法:
    //没有返回值也不写void
    //函数名与类名相同
    //可以有参数,因此可以发生重载
    //程序调用对象时会自动调用构造,无需手动调用且只会调用一次
    
    //析构函数语法:
    //没有返回值也不写void
    //函数名与类名相同,前面加~
    //不可以有参数,因此不可以发生重载
    //对象销毁前会自动调用析构,无需手动调用且只会调用一次
    
    class Preson
    {
    public:
        //构造函数
        Preson()
        {
            cout << "Preson构造函数调用" << endl;
        }
        //析构函数
        ~Preson()
        {
            cout << "Preson析构函数调用" << endl;
        }
    };
    
    void test01()
    {
        Preson p;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    构造函数和析构函数
    #include <iostream>
    
    using namespace std;
    
    //按参数分:有参构造,无参构造
    //按类型分:普通构造,拷贝构造
    
    //三种调用方式:括号法,显示法,隐式转换法 
    
    class Preson
    {
    public:
        int age;
    public:
        //无参(默认)构造函数
        Preson()
        {
            cout << "无参构造函数调用" << endl;
        }
        //有参构造函数
        Preson(int a)
        {
            age = a;
            cout << "有参构造函数调用" << endl;
        }
        //拷贝构造函数
        Preson(const Preson& p)
        {
            age = p.age;
            cout << "拷贝构造函数调用" << endl;
    
        }
        //析构函数
        ~Preson()
        {
            cout << "析构函数调用" << endl;
        }
    };
    
    //调用无参构造函数
    void test01()
    {
        Preson p;
    }
    
    //调用有参构造函数
    void test02()
    {
        //括号法
        Preson p1(10);
        //Preson p2(); //调用无参构造函数不要这样写,编译器会认为是函数声明
    
        //显示法
        Preson p2 = Preson(10);
        Preson p3 = Preson(p2);
        //Preson(10) //这是匿名对象,当前行结束之后马上析构
    
        //隐式转换法
        Preson p4 = 10; //Preson p4 = Preson(10);
        Preson p5 = p4; //Preson p5 = Preson(p4);
        //Preson p5(p4); //不能利用拷贝构造函数初始化匿名对象,编译器会认为是函数声明
    }
    
    int main()
    {
        //test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    构造函数分类及调用
    #include <iostream>
    
    using namespace std;
    
    //拷贝构造函数调用三种情况:
    //使用一个已经创建完毕的对象初始化一个新对象
    //值传递方式给函数参数传值
    //值传递方式返回局部对象
    
    class Preson
    {
    public:
        int age;
    public:
        //无参(默认)构造函数
        Preson()
        {
            age = 0;
            cout << "无参构造函数调用" << endl;
        }
        //有参构造函数
        Preson(int a)
        {
            age = a;
            cout << "有参构造函数调用" << endl;
        }
        //拷贝构造函数
        Preson(const Preson& p)
        {
            age = p.age;
            cout << "拷贝构造函数调用" << endl;
    
        }
        //析构函数
        ~Preson()
        {
            cout << "析构函数调用" << endl;
        }
    };
    
    //使用一个已经创建完毕的对象初始化一个新对象
    void test01()
    {
        Preson p1(100);
        Preson p2(p1);
        Preson p3 = p1;
    }
    
    //值传递方式给函数参数传值
    void doWork01(Preson p)
    {
    
    }
    void test02()
    {
        Preson p;
        doWork01(p);
    }
    
    //值传递方式返回局部对象
    Preson doWork02()
    {
        Preson p;
        cout << (int)&p << endl;
        return p;
    }
    void test03()
    {
        Preson p = doWork02();
        cout << (int)&p << endl;
    }
    
    int main()
    {
        //test01();
    
        //test02();
    
        test03();
    
        system("pause");
    
        return 0;
    }
    拷贝构造函数调用时机
    #include <iostream>
    
    using namespace std;
    
    //默认情况下,C++编译器至少给一个类添加三个函数
    //默认无参构造函数
    //默认析构函数
    //默认拷贝构造函数
    
    //若用户定义有参构造函数,C++编译器不再提供默认无参构造函数,但会提供默认拷贝构造函数
    //若用户定义拷贝构造函数,C++编译器什么也不提供
    
    class Preson
    {
    public:
        int age;
    public:
        //无参(默认)构造函数
        Preson()
        {
            cout << "无参构造函数调用" << endl;
        }
        //有参构造函数
        Preson(int a)
        {
            age = a;
            cout << "有参构造函数调用" << endl;
        }
        //拷贝构造函数
        Preson(const Preson& p)
        {
            age = p.age;
            cout << "拷贝构造函数调用" << endl;
    
        }
        //析构函数
        ~Preson()
        {
            cout << "析构函数调用" << endl;
        }
    };
    
    void test01()
    {
        Preson p1(100);
        Preson p2(p1); //若不写拷贝构造函数,C++编译器会自动添加并做浅拷贝操作
        cout << "p2年龄 = " << p2.age << endl;
    }
    
    void test02()
    {
        Preson p1;
        Preson p2(10);
        Preson p3(p2);
    
        Preson p4;
        Preson p5(10);
        Preson p6(p5);
    }
    
    int main()
    {
        //test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    构造函数调用规则
    #include <iostream>
    
    using namespace std;
    
    //浅拷贝:简单的赋值拷贝操作
    //深拷贝:在堆区重新申请空间进行拷贝操作
    
    class Preson
    {
    public:
        int m_age;
        int* m_hieght;
    public:
        //无参(默认)构造函数
        Preson()
        {
            cout << "无参构造函数调用" << endl;
        }
        //有参构造函数
        Preson(int age, int height)
        {
            m_age = age;
            m_hieght = new int(height);
            cout << "有参构造函数调用" << endl;
        }
        //拷贝构造函数
        Preson(const Preson& p)
        {
            m_age = p.m_age;
            m_hieght = new int(*p.m_hieght);     //如果类属性是在堆区开辟的,一定要自己提供拷贝函数,防止浅拷贝带来的问题
            cout << "拷贝构造函数调用" << endl;     //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来重复释放堆区问题
        }
        //析构函数
        ~Preson()
        {
            if (m_hieght != NULL)
            {
                delete m_hieght;
            }
            cout << "析构函数调用" << endl;
        }
    };
    
    void test01()
    {
        Preson p1(18, 100);
        Preson p2(p1);
        cout << "p1年龄 = " << p1.m_age << endl;
        cout << "p1体重 = " << *p1.m_hieght << endl;
        cout << "p2年龄 = " << p2.m_age << endl;
        cout << "p2体重 = " << *p2.m_hieght << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    浅拷贝与深拷贝
    #include <iostream>
    
    using namespace std;
    
    class Preson
    {
    private:
        int m_a;
        int m_b;
        int m_c;
    public:
        //传统方式
        /*Preson(int a, int b, int c)
        {
            m_a = a;
            m_b = b;
            m_c = c;
        }*/
    
        Preson(int a, int b, int c) :m_a(a), m_b(b), m_c(c)
        {
    
        }
    
        void printPreson()
        {
            cout << "mA = " << m_a << endl;
            cout << "mB = " << m_b << endl;
            cout << "mC = " << m_c << endl;
        }
    };
    
    int main()
    {
        Preson p(1, 2, 3);
        p.printPreson();
    
        system("pause");
    
        return 0;
    }
    初始化列表
    #include <iostream>
    
    using namespace std;
    
    //类1中包含另一个类2时,
    //构造函数先执行类2在执行类1
    //析构函数先执行类1在执行类2
    
    class Phone
    {
    public:
        string m_phoneName;
    public:
        Phone(string name)
        {
            m_phoneName = name;
            cout << "Phone构造函数" << endl;
        }
        ~Phone()
        {
            cout << "Phone析构函数" << endl;
        }
    };
    
    class Preson
    {
    public:
        string m_name;
        Phone m_phoneNmae;
    public:
        Preson(string name, string pname) :m_name(name), m_phoneNmae(pname)
        {
            cout << "Preson构造函数" << endl;
        }
        ~Preson()
        {
            cout << "Preson析构函数" << endl;
        }
        void playShow()
        {
            cout << m_name << " 使用 " << m_phoneNmae.m_phoneName << " 牌子手机" << endl;
        }
    };
    
    void test01()
    {
        Preson p("张三", "IphoneX");
        p.playShow();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    类中有类
    #include <iostream>
    
    using namespace std;
    
    //静态成员变量:
    //所有对象共享同一份数据
    //在编译阶段分配内存
    //类内声明类外初始化
    
    class Preson
    {
    public:
        static int m_a;
    private:
        static int m_b;
    };
    
    int Preson::m_a = 100;
    int Preson::m_b = 1000;
    
    void test01()
    {
        //通过对象访问
        Preson p1;
        p1.m_a = 100;
        cout << "p1.m_a " << p1.m_a << endl;
    
        //共享同一份数据
        Preson p2;
        p2.m_a = 200;
        cout << "p1.m_a " << p1.m_a << endl;
        cout << "p2.m_a " << p2.m_a << endl;
    
        //通过类名访问
        cout << "m_a " << Preson::m_a << endl;
    
        //cout << "m_b " << Preson::m_b << endl; //私有权限访问不到
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    静态成员变量
    #include <iostream>
    
    using namespace std;
    
    //静态成员函数:
    //所有对象共享同一个函数
    //静态成员函数只能访问静态成员变量
    
    class Preson
    {
    public:
        static int m_a;
        int m_b;
    public:
        static void func1()
        {
            m_a = 100;
            //m_b = 100;
            cout << "func1()调用" << endl;
        }
    private:
        static void func2()
        {
            cout << "func2()调用" << endl;
        }
    };
    
    int Preson::m_a = 1000;
    
    void test01()
    {
        //通过对象访问
        Preson p1;
        p1.func1();
    
        //通过类名访问
        Preson::func1();
    
        //Preson::func2();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    静态成员函数
    #include <iostream>
    
    using namespace std;
    
    //在C++中,类的成员变量和成员函数分开存储
    //只有非静态成员变量占对象空间
    
    class Preson
    {
    public:
        Preson()
        {
    
        }
    
        int m_a;
    
        /*static int m_b;
    
        void func1()
        {
    
        }
    
        static void func2()
        {
    
        }*/
    };
    
    int main()
    {
        cout << sizeof(Preson) << endl;
    
        system("pause");
    
        return 0;
    }
    成员变量和成员函数分开存储
    #include <iostream>
    
    using namespace std;
    
    //this指针指向被调用成员函数所属的对象
    //this指针是隐含在每一个非静态成员函数内的一种指针
    //this指针不需要定义,直接使用即可
    
    //this指针用途:
    //1、当形参和成员变量重名时,可以用this指针来区分
    //2、在类的非静态成员函数中返回对象本身,可使用return *this
    
    class Preson
    {
    
    public:
        int age;
    public:
        Preson(int age)
        {
            //1、
            this->age = age;
        }
        //2、
        Preson& presonAdd(Preson p)
        {
            this->age += p.age;
            return *this;
        }
    };
    
    void test01()
    {
        Preson p1(10);
        cout << "p1.age = " << p1.age << endl;
    
        Preson p2(10);
        p2.presonAdd(p1).presonAdd(p1).presonAdd(p1);
        cout << "p2.age = " << p2.age << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    this指针概念
    #include <iostream>
    
    using namespace std;
    
    class Preson
    {
    public:
        int m_age;
    public:
        void showClassName()
        {
            cout << "我是showClassName()" << endl;
        }
        void showPreson()
        {
            if (this == NULL)
            {
                return;
            }
            cout << "我是showPreson()" << endl;
        }
    };
    
    void test01()
    {
        Preson* p = NULL;
        p->showClassName();
        p->showPreson();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    空指针访问成员函数
    #include <iostream>
    
    using namespace std;
    
    //成员函数后加const称为常函数
    //常函数内不可以修改成员属性
    //成员属性在声明时加mutable关键字后,在常函数中依然可以修改
    
    //声明对象前加const称为常对象
    //常对象只能调用常函数
    
    class Preson
    {
    public:
        int m_a;
        mutable int m_b;
    public:
        Preson()
        {
            m_a = 0;
            m_b = 0;
        }
        //this指针本质为一个指针常量,指针指向不可以修改
        //如果想指针指向的值也不可以修改,需声明常函数
        void func1() const
        {
            //this = NULL; //不能修改指针指向
    
            //this->m_a = 100; //不能修改指针指向的值
    
            this->m_b = 100;
        }
    };
    
    void test01()
    {
        //常对象
        const Preson p;
        //p.m_a = 100;
        p.m_b = 100;
        p.func1();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    常函数和常对象
    #include <iostream>
    
    using namespace std;
    
    //全局函数做友元
    
    class Building
    {
        friend void goodGay(Building* b);
    
    public:
        string m_SittingRoom;
    private:
        string m_BedRoom;
    public:
        Building()
        {
            this->m_SittingRoom = "客厅";
            this->m_BedRoom = "卧室";
        }
    };
    
    void goodGay(Building* b)
    {
        cout << "好基友正在访问:" << b->m_SittingRoom << endl;
        cout << "好基友正在访问:" << b->m_BedRoom << endl;
    }
    
    void test01()
    {
        Building b;
        goodGay(&b);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    全局函数做友元
    #include <iostream>
    
    using namespace std;
    
    //类做友元
    
    class Building;
    
    class GoodGay
    {
    private:
        Building* b;
    public:
        GoodGay();
        void visit();
    };
    
    class Building
    {
        friend class GoodGay;
    
    public:
        string m_SittingRoom;
    private:
        string m_BedRoom;
    public:
        Building();
    };
    
    Building::Building()
    {
        this->m_SittingRoom = "客厅";
        this->m_BedRoom = "卧室";
    }
    
    GoodGay::GoodGay()
    {
        b = new Building;
    }
    
    void GoodGay::visit()
    {
        cout << "好基友正在访问:" << b->m_SittingRoom << endl;
        cout << "好基友正在访问:" << b->m_BedRoom << endl;
    }
    
    void test01()
    {
        GoodGay gg;
        gg.visit();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    类做友元
    #include <iostream>
    
    using namespace std;
    
    //成员函数做友元
    
    class Building;
    
    class GoodGay
    {
    private:
        Building* b;
    public:
        GoodGay();
        void visit();
        void visit2();
    };
    
    class Building
    {
        friend void GoodGay::visit();
    
    public:
        string m_SittingRoom;
    private:
        string m_BedRoom;
    public:
        Building();
    };
    
    Building::Building()
    {
        this->m_SittingRoom = "客厅";
        this->m_BedRoom = "卧室";
    }
    
    GoodGay::GoodGay()
    {
        b = new Building;
    }
    
    void GoodGay::visit()
    {
        cout << "好基友正在访问:" << b->m_SittingRoom << endl;
        cout << "好基友正在访问:" << b->m_BedRoom << endl;
    }
    
    void GoodGay::visit2()
    {
        cout << "好基友正在访问:" << b->m_SittingRoom << endl;
        //cout << "好基友正在访问:" << b->m_BedRoom << endl;
    }
    
    void test01()
    {
        GoodGay gg;
        gg.visit();
        gg.visit2();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    成员函数做友元
    #include <iostream>
    
    using namespace std;
    
    //加号运算符重载
    //实现两个自定义数据类型相加运算
    
    class Preson
    {
    public:
        int m_a;
        int m_b;
    public:
        Preson()
        {
    
        }
        Preson(int a, int b)
        {
            this->m_a = a;
            this->m_b = b;
        }
        //成员函数实现
        /*Preson operator+(Preson& p)
        {
            Preson val;
            val.m_a = this->m_a + p.m_a;
            val.m_b = this->m_b + p.m_b;
            return val;
        }*/
    };
    
    //全局函数实现
    Preson operator+(Preson& p1, Preson& p2)
    {
        Preson val(0, 0);
        val.m_a = p1.m_a + p2.m_a;
        val.m_b = p1.m_b + p2.m_b;
        return val;
    }
    
    //运算符重载的同时也可以发生函数重载
    Preson operator+(Preson& p1, int n)
    {
        Preson val(0, 0);
        val.m_a = p1.m_a + n;
        val.m_b = p1.m_b + n;
        return val;
    }
    
    void test01()
    {
        Preson p1(10, 20);
        Preson p2(10, 20);
    
        Preson p3 = p1 + p2;
    
        Preson p4 = p3 + 10;
    
        cout << "m_a = " << p3.m_a << endl;
        cout << "m_b = " << p3.m_b << endl;
    
        cout << "m_a = " << p4.m_a << endl;
        cout << "m_b = " << p4.m_b << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    加号运算符重载
    #include <iostream>
    
    using namespace std;
    
    //左移运算符重载
    //可以输出自定义数据类型
    
    class Preson
    {
        friend ostream& operator<<(ostream& cout, Preson& p);
    
    private:
        int m_a;
        int m_b;
    public:
        Preson(int a, int b)
        {
            this->m_a = a;
            this->m_b = b;
        }
        //成员函数实现不了
        //p << cout 不是我们想要的格式
    };
    
    //全局函数实现
    ostream& operator<<(ostream& out, Preson& p)
    {
        out << "m_a = " << p.m_a << endl;
        out << "m_b = " << p.m_b << endl;
        return out;
    }
    
    void test01()
    {
        Preson p(10, 100);
        cout << p << endl; //链式编程
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    左移运算符重载
    #include <iostream>
    
    using namespace std;
    
    //递增运算符重载
    
    class myInt
    {
        friend ostream& operator<<(ostream& out, myInt mi);
    
    private:
        int m_num;
    public:
        myInt()
        {
            m_num = 10;
        }
        //前置++
        myInt& operator++()
        {
            //先++在return
            m_num++;
            return *this;
        }
        //后置++
        myInt operator++(int)
        {
            //先return在++
            myInt mi = *this;
            m_num++;
            return mi;
        }
    };
    
    ostream& operator<<(ostream& out, myInt mi)
    {
        out << mi.m_num;
        return out;
    }
    
    //前置++
    void test01()
    {
        myInt mi;
        cout << ++mi << endl;
        cout << mi << endl;
    }
    
    //后置++
    void test02()
    {
        myInt mi;
        cout << mi++ << endl;
        cout << mi << endl;
    }
    
    int main()
    {
        test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    递增运算符重载
    #include <iostream>
    
    using namespace std;
    
    //赋值运算符重载
    
    class Preson
    {
    public:
        int* m_age;
    public:
        Preson(int age)
        {
            m_age = new int(age);
        }
        Preson& operator=(Preson& p)
        {
            if (m_age != NULL)
            {
                delete m_age;
                m_age = NULL;
            }
    
            //编译器提供的是浅拷贝
            //m_age = p.m_age;
    
            //深拷贝
            m_age = new int(*p.m_age);
            return *this;
        }
        ~Preson()
        {
            if (m_age != NULL)
            {
                delete m_age;
                m_age = NULL;
            }
        }
    };
    
    void test01()
    {
        Preson p1(10);
        Preson p2(20);
        Preson p3(30);
    
        p3 = p2 = p1;
    
        cout << "p1年龄 = " << *p1.m_age << endl;
        cout << "p2年龄 = " << *p2.m_age << endl;
        cout << "p3年龄 = " << *p3.m_age << endl;
    }
    
    int main()
    {
        test01();
    
        int a = 10;
        int b = 20;
        int c = 30;
    
        c = b = a;
    
        cout << "a = " << a << endl;
        cout << "b = " << b << endl;
        cout << "c = " << c << endl;
    
        system("pause");
    
        return 0;
    }
    赋值运算符重载
    #include <iostream>
    
    using namespace std;
    
    //关系运算符重载
    
    class Preson
    {
    public:
        string m_name;
        int m_age;
    public:
        Preson(string name, int age)
        {
            this->m_name = name;
            this->m_age = age;
        }
        bool operator==(Preson& p)
        {
            if (this->m_name == p.m_name && this->m_age == p.m_age)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        bool operator!=(Preson& p)
        {
            if (this->m_name == p.m_name && this->m_age == p.m_age)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    };
    
    void test01()
    {
        Preson p1("张三", 20);
        Preson p2("张三", 22);
    
        if (p1 == p2)
        {
            cout << "p1==p2" << endl;
        }
        else
        {
            cout << "p1!=p2" << endl;
        }
    
        if (p1 != p2)
        {
            cout << "p1!=p2" << endl;
        }
        else
        {
            cout << "p1==p2" << endl;
        }
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    关系运算符重载
    #include <iostream>
    
    using namespace std;
    
    //函数调用运算符重载
    //也称为仿函数(),没有固定写法,非常灵活
    
    class myPrint
    {
    public:
        void operator()(string s)
        {
            cout << s << endl;
        }
    };
    
    void test01()
    {
        myPrint mp;
        mp("hello world");
    }
    
    class myAdd
    {
    public:
        int operator()(int a, int b)
        {
            return a + b;
        }
    };
    
    void test02()
    {
        myAdd ma;
        int n = ma(10, 20);
        cout << "n = " << n << endl;
    
        //匿名对象调用
        cout << "myAdd()(1000, 1000) = " << myAdd()(1000, 1000) << endl;
    }
    
    int main()
    {
        test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    函数调用运算符重载
    #include <iostream>
    
    using namespace std;
    
    //继承:减少重复代码
    
    //子类,父类
    //派生类,基类
    
    class basePage
    {
    public:
        void header()
        {
            cout << "公共头部" << endl;
        }
        void footer()
        {
            cout << "公共底部" << endl;
        }
    };
    
    class Java :public basePage
    {
    public:
        void concent()
        {
            cout << "Java学习视频" << endl;
        }
    };
    
    class Python :public basePage
    {
    public:
        void concent()
        {
            cout << "Python学习视频" << endl;
        }
    };
    
    class CPP :public basePage
    {
    public:
        void concent()
        {
            cout << "CPP学习视频" << endl;
        }
    };
    
    void test01()
    {
        Java ja;
        ja.header();
        ja.footer();
        ja.concent();
    
        Python py;
        py.header();
        py.footer();
        py.concent();
    
        CPP cp;
        cp.header();
        cp.footer();
        cp.concent();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    继承基本语法
    #include <iostream>
    
    using namespace std;
    
    //公有继承
    class Base1
    {
    public:
        int m_a;
    protected:
        int m_b;
    private:
        int m_c;
    };
    class Son1 :public Base1
    {
        void func()
        {
            m_a; //可访问,public权限
            m_b; //可访问,protected权限
            //m_c; //不可访问
        }
    };
    void test01()
    {
        Son1 s1;
        s1.m_a;
    }
    
    //保护继承
    class Base2
    {
    public:
        int m_a;
    protected:
        int m_b;
    private:
        int m_c;
    };
    class Son2 :protected Base2
    {
        void func()
        {
            m_a; //可访问,protected权限
            m_b; //可访问,protected权限
            //m_c; //不可访问
        }
    };
    void test02()
    {
        Son2 s2;
    }
    
    //私有继承
    class Base3
    {
    public:
        int m_a;
    protected:
        int m_b;
    private:
        int m_c;
    };
    class Son3 :private Base3
    {
        void func()
        {
            m_a; //可访问,private权限
            m_b; //可访问,private权限
            //m_c; //不可访问
        }
    };
    void test03()
    {
        Son3 s3;
    }
    
    int main()
    {
        test01();
    
        test02();
    
        test03();
    
        system("pause");
    
        return 0;
    }
    继承方式
    #include <iostream>
    
    using namespace std;
    
    //父类中私有成员也被子类继承了,只是被编译器隐藏访问不到
    
    class Base
    {
    public:
        int m_a;
    protected:
        int m_b;
    private:
        int m_c;
    };
    
    class Son :public Base
    {
    public:
        int m_d;
    };
    
    void test01()
    {
        cout << sizeof(Son) << endl; //16
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    继承中的对象模型
    #include <iostream>
    
    using namespace std;
    
    //继承中先调用父类构造函数,在调用子类构造函数
    //析构函数与构造函数调用顺序相反
    
    class Base
    {
    public:
        Base()
        {
            cout << "Base()构造函数" << endl;
        }
        ~Base()
        {
            cout << "Base()析构函数" << endl;
        }
    };
    
    class Son :public Base
    {
    public:
        Son()
        {
            cout << "Son()构造函数" << endl;
        }
        ~Son()
        {
            cout << "Son()析构函数" << endl;
        }
    };
    
    void test01()
    {
        Son s;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    继承中构造函数与析构函数调用顺序
    #include <iostream>
    
    using namespace std;
    
    //子类对象可以直接访问子类同名成员
    //子类对象加作用域可以访问父类同名成员
    //子类和父类有同名成员函数时,子类会隐藏父类同名成员函数,若想访问需加作用域
    
    class Base
    {
    public:
        int m_a;
    public:
        Base()
        {
            m_a = 100;
        }
        void func()
        {
            cout << "Base  func()调用" << endl;
        }
        void func(int a)
        {
            cout << "Base  func(int a)调用" << endl;
        }
    };
    
    class Son :public Base
    {
    public:
        int m_a;
    public:
        Son()
        {
            m_a = 200;
        }
        void func()
        {
            cout << "Son  func()调用" << endl;
        }
    };
    
    void test01()
    {
        Son s;
        cout << "Son的m_a = " << s.m_a << endl;
        cout << "Base的m_a = " << s.Base::m_a << endl;
    
        s.func();
        s.Base::func();
        s.Base::func(10);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    继承中同名成员处理方式
    #include <iostream>
    
    using namespace std;
    
    class Base
    {
    public:
        static int m_a;
    public:
        static void func()
        {
            cout << "Base  func()调用" << endl;
        }
        static void func(int a)
        {
            cout << "Base  func(int a)调用" << endl;
        }
    };
    
    int Base::m_a = 100;
    
    class Son :public Base
    {
    public:
        static int m_a;
    public:
        static void func()
        {
            cout << "Son  func()调用" << endl;
        }
    };
    
    int Son::m_a = 200;
    
    //同名成员属性
    void test01()
    {
        //通过对象访问
        Son s;
        cout << "Son的m_a = " << s.m_a << endl;
        cout << "Base的m_a = " << s.Base::m_a << endl;
    
        //通过类名访问
        cout << "Son的m_a = " << Son::m_a << endl;
        cout << "Base的m_a = " << Son::Base::m_a << endl;
    }
    
    //同名成员函数
    void test02()
    {
        //通过对象访问
        Son s;
        s.func();
        s.Base::func();
    
        //通过类名访问
        Son::func();
        //Base::代表作用域
        Son::Base::func();
        Son::Base::func(100);
    }
    
    int main()
    {
        test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    继承中同名静态成员处理方式
    #include <iostream>
    
    using namespace std;
    
    class Base1
    {
    public:
        int m_a;
    public:
        Base1()
        {
            m_a = 100;
        }
    };
    
    class Base2
    {
    public:
        int m_a;
    public:
        Base2()
        {
            m_a = 200;
        }
    };
    
    class Son :public Base1, public Base2
    {
    public:
        int m_c;
        int m_d;
    public:
        Son()
        {
            m_c = 300;
            m_d = 400;
        }
    };
    
    void test01()
    {
        Son s;
        cout << sizeof(Son) << endl;
        cout << s.Base1::m_a << endl;
        cout << s.Base2::m_a << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    多继承语法
    #include <iostream>
    
    using namespace std;
    
    //菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费且毫无意义
    //利用虚继承解决菱形继承问题
    
    class Animal
    {
    public:
        int m_age;
    };
    
    class Yang :virtual public Animal
    {
    
    };
    
    class Tuo :virtual public Animal
    {
    
    };
    
    class YangTuo :public Yang, public Tuo
    {
    
    };
    
    void test01()
    {
        YangTuo yt;
        yt.Yang::m_age = 100;
        yt.Tuo::m_age = 200;
    
        cout << "yt.Yang::m_age = " << yt.Yang::m_age << endl;
        cout << "yt.Tuo::m_age = " << yt.Tuo::m_age << endl;
        cout << "yt.m_age = " << yt.m_age << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    菱形继承
    #include <iostream>
    
    using namespace std;
    
    //多态满足条件:
    //有继承关系
    //子类重写父类中的虚函数
    
    //多态使用条件
    //父类指针或引用指向子类对象
    //重写时,函数返回类型、函数名、参数列表要完全一致
    
    class Animal
    {
    public:
        //虚函数
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
    };
    
    class Cat :public Animal
    {
    public:
        void speak()
        {
            cout << "小猫在说话" << endl;
        }
    };
    
    class Dog :public Animal
    {
    public:
        void speak()
        {
            cout << "小狗在说话" << endl;
        }
    };
    
    void doSpeak(Animal& a)
    {
        a.speak();
    }
    
    void test01()
    {
        Cat cat;
        doSpeak(cat);
    
        Dog dog;
        doSpeak(dog);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    多态的基本概念
    #include <iostream>
    
    using namespace std;
    
    class jiSuanQi
    {
    public:
        int m_num1;
        int m_num2;
    public:
        virtual int getResult()
        {
            return 0;
        }
    };
    
    class jiajiSuanQi :public jiSuanQi
    {
    public:
        int getResult()
        {
            return m_num1 + m_num2;
        }
    };
    
    class jianjiSuanQi :public jiSuanQi
    {
    public:
        int getResult()
        {
            return m_num1 - m_num2;
        }
    };
    
    class chengjiSuanQi :public jiSuanQi
    {
    public:
        int getResult()
        {
            return m_num1 * m_num2;
        }
    };
    
    class chujiSuanQi :public jiSuanQi
    {
    public:
        int getResult()
        {
            return m_num1 / m_num2;
        }
    
    };
    
    void test01()
    {
        //加法
        jiSuanQi* jsq = new jiajiSuanQi;
        jsq->m_num1 = 200;
        jsq->m_num2 = 100;
        cout << "加法 = " << jsq->getResult() << endl;
        delete jsq;
    
        //减法
        jsq = new jianjiSuanQi;
        jsq->m_num1 = 200;
        jsq->m_num2 = 100;
        cout << "减法 = " << jsq->getResult() << endl;
        delete jsq;
    
        //乘法
        jsq = new chengjiSuanQi;
        jsq->m_num1 = 200;
        jsq->m_num2 = 100;
        cout << "乘法 = " << jsq->getResult() << endl;
        delete jsq;
    
        //除法
        jsq = new chujiSuanQi;
        jsq->m_num1 = 200;
        jsq->m_num2 = 100;
        cout << "除法 = " << jsq->getResult() << endl;
        delete jsq;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    多态计算器
    #include <iostream>
    
    using namespace std;
    
    //在多态中,通常父类中的虚函数是毫无意义的,主要都是调用子类中重写的内容
    //因此可以将虚函数改为纯虚函数
    //当类中有了纯虚函数,这个类也称为抽象类
    
    //抽象类特点:
    //无法实例化对象
    //子类必须重写抽象类中的纯虚函数,否则也属于抽象类
    
    class Base
    {
    public:
        //纯虚函数
        virtual void func() = 0;
    };
    
    class Son :public Base
    {
    public:
        void func()
        {
            cout << "func()调用" << endl;
        }
    };
    
    void test01()
    {
        Base* base = NULL;
        //base = new Base;
        base = new Son;
        base->func();
        delete base;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    纯虚函数和抽象类
    #include <iostream>
    
    using namespace std;
    
    class zhiZuoYinPin
    {
    public:
        virtual void shaoShui() = 0;
        virtual void chongPao() = 0;
        virtual void heTa() = 0;
        void liuCheng()
        {
            shaoShui();
            chongPao();
            heTa();
        }
    };
    
    class Coffee :public zhiZuoYinPin
    {
        void shaoShui()
        {
            cout << "加热农夫山泉" << endl;
        }
        void chongPao()
        {
            cout << "冲泡咖啡" << endl;
        }
        void heTa()
        {
            cout << "喝咖啡" << endl;
        }
    };
    
    class Tea :public zhiZuoYinPin
    {
        void shaoShui()
        {
            cout << "加热百岁山" << endl;
        }
        void chongPao()
        {
            cout << "冲泡龙井" << endl;
        }
        void heTa()
        {
            cout << "喝龙井" << endl;
        }
    };
    
    void doWork(zhiZuoYinPin* zzyp)
    {
        zzyp->liuCheng();
        delete zzyp;
    }
    
    void test01()
    {
        doWork(new Coffee);
        doWork(new Tea);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    多态制作饮品
    #include <iostream>
    
    using namespace std;
    
    //使用多态时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构函数
    //解决办法:将父类中的析构函数改为虚析构或纯虚析构
    
    //虚析构和纯虚析构
    //共性:
    //可以解决父类指针释放子类对象
    //都需要有具体的函数实现
    //区别:
    //如果是纯虚析构函数,该类属于抽象类,无法实例化
    //如果子类中没有堆区数据,可以不写虚析构或纯虚析构
    
    class Animal
    {
    public:
        virtual void speak() = 0;
    
        Animal()
        {
            cout << "Animal()构造函数调用" << endl;
        }
    
        //虚析构函数
        /*virtual ~Animal()
        {
            cout << "Animal()虚析构函数调用" << endl;
        }*/
    
        //纯虚析构函数
        virtual ~Animal() = 0;
    };
    
    Animal::~Animal()
    {
        cout << "Animal()纯虚析构函数调用" << endl;
    }
    
    class Cat :public Animal
    {
    public:
        string* m_name;
    
    public:
        Cat(string name)
        {
            cout << "Cat构造函数调用" << endl;
            m_name = new string(name);
        }
    
        virtual ~Cat()
        {
            cout << "Cat析构函数调用" << endl;
            if (this->m_name != NULL)
            {
                delete m_name;
                m_name = NULL;
            }
        }
    
        void speak()
        {
            cout << *m_name << "小猫在说话" << endl;
        }
    };
    
    void test01()
    {
        Animal* a = new Cat("Tom");
        a->speak();                   //通过父类指针去释放,会导致子类对象清理不干净,造成内存泄露
        delete a;                   //给父类增加一个虚析构函数或纯虚析构函数
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    虚析构函数和纯虚析构函数
    #include <iostream>
    
    using namespace std;
    
    //C++中对文件操作需包含头文件<fstream>
    #include <fstream>
    
    //文件类型分为两种:
    //文本文件,以ASCII码形式存储
    //二进制文件,以二进制形式存储
    
    //操作文件的三大类:
    //ofstream,写操作
    //ifstream,读操作
    //fstream,写读操作
    
    //文本文件,写文件步骤:
    //包含头文件
    //创建流对象
    //打开文件
    //写数据
    //关闭文件
    
    //文件打开方式:
    //ios::in 为读文件而打开文件
    //ios::out 为写文件而打开文件
    //ios::ate 初始位置:文件尾
    //ios::app 追加方式写文件
    //ios::trunc 如果文件存在先删除,在创建
    //ios::binary 二进制方式
    
    //文件打开方式可以配合 | 操作符使用
    //如二进制方式写文件 ios::binary | ios::out
    
    void test01()
    {
        ofstream ofs;
        ofs.open("test.txt", ios::out);
        ofs << "姓名 = 张三" << endl;
        ofs << "性别 = 男" << endl;
        ofs.close();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    文本文件(写文件)
    #include <iostream>
    
    using namespace std;
    
    #include <fstream>
    
    //文本文件读文件步骤:
    //包含头文件
    //创建流对象
    //打开文件并判断文件是否打开成功
    //读数据
    //关闭文件
    
    void test01()
    {
        ifstream ifs;
        ifs.open("test.txt", ios::in);
        if (!ifs.is_open())
        {
            cout << "文件打开失败" << endl;
            return;
        }
    
        //1
        /*char buff[1024] = { 0 };
        while (ifs >> buff)
        {
            cout << buff << endl;
        }*/
    
        //2
        /*char buff[1024] = { 0 };
        while (ifs.getline(buff, sizeof(buff)))
        {
            cout << buff << endl;
        }*/
    
        //3
        char c;
        while ((c = ifs.get()) != EOF)
        {
            cout << c;
        }
    
        ifs.close();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    文本文件(读文件)
    #include <iostream>
    
    using namespace std;
    
    #include <fstream>
    
    //ostream& write(char* buffer , int len)
    //buffer指向内存中一段存储空间,len是读写字节数
    
    class Preson
    {
    public:
        char m_name[64];
        int m_age;
    };
    
    void test01()
    {
        ofstream ofs("Preson.txt", ios::out | ios::binary);
    
        Preson p{ "李四",18 };
    
        ofs.write((const char*)&p, sizeof(p));
    
        ofs.close();
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    二进制文件(写文件)
    #include <iostream>
    
    using namespace std;
    
    #include <fstream>
    
    //istream& read(char* buffer , int len)
    //buffer指向内存中一段存储空间,len是读写字节数
    
    class Preson
    {
    public:
        char m_name[64];
        int m_age;
    };
    
    void test01()
    {
        ifstream ifs("Preson.txt", ios::in | ios::binary);
    
        if (!ifs.is_open())
        {
            cout << "文件打开失败" << endl;
            return;
        }
    
        Preson p;
    
        ifs.read((char*)&p, sizeof(p));
    
        cout << "姓名 = " << p.m_name << endl;
        cout << "年龄 = " << p.m_age << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    二进制文件(读文件)

    end

  • 相关阅读:
    简单了解enum
    PowerDesigner CDM 生成PDM时,外键的命名规则
    HADOOP docker(五):hadoop用户代理 Proxy user
    记一次云安全的安全事件应急响应
    docker学习笔记--重基础使用
    Elasticsearch学习随笔(二)-- Index 和 Doc 查询新建API总结
    Elasticsearch学习随笔(一)--原理理解与5.0核心插件部署过程
    ntopng-一款流量审计框架的安装以及应用
    Suricata规则编写——常用关键字
    浅谈运维中的安全问题-FTP篇
  • 原文地址:https://www.cnblogs.com/huangxuQaQ/p/12197654.html
Copyright © 2020-2023  润新知