美文网首页
C++基础一文通(四)面向对象

C++基础一文通(四)面向对象

作者: 熊爸天下_56c7 | 来源:发表于2022-08-10 08:38 被阅读0次

    一. 面向对象

    1. 创建类

    语法: class 类名{ 访问权限: 属性 / 行为 };

    例如: 创建学生类

    #include <iostream>
    using namespace std;
    
    //学生类
    class Student
    {
    public:
        void setName(string name)
        {
            m_name = name;
        }
        void setID(int id)
        {
            m_id = id;
        }
    
        void showStudent()
        {
            cout << "name:" << m_name << " ID:" << m_id << endl;
        }
    
    public:
        string m_name;
        int m_id;
    };
    
    int main()
    {
    
        Student stu; // 实例化
    
        stu.m_name = "ddd";
        stu.m_id = 123;
        // 操作属性
        cout << "stu.m_name : " << stu.m_name << endl;
        cout << "stu.m_id : " << stu.m_id << endl;
    
        // 使用方法
        stu.setName("anny");
        stu.setID(7);
        stu.showStudent();
    
        return 0;
    }
    

    2. 类的权限

    类在设计时,可以把属性和行为放在不同的权限下,加以控制

    访问权限有三种:

    • public 公共权限 (类内可以访问 类外可以访问)
    • protected 保护权限 (类内可以访问 类外不可以访问, 子类可以访问)
    • private 私有权限 (类内可以访问 类外不可以访问, 子类不可以访问, 这是类默认的!!!!)

    对于不能访问的属性和方法, 只能通过暴露接口来访问
    类的默认权限是private!!!!!!!!

    3. 在C++中 struct和class唯一的区别就在于 默认的访问权限不同

    struct 默认权限为公共
    struct Student
    {
        string m_name;
        void set_id(int a)
        {
            m_id = a;
        }
        void show_id()
        {
            cout << m_id << endl;
        }
    //struct默认public, 如果需要private, 则需要声明
    private:
        int m_id;
    };
    
    int main()
    {
    
        Student stu;
        stu.m_name = "ddd";
        stu.set_id(123);
        // 操作属性
        cout << "stu.m_name : " << stu.m_name << endl;
        stu.show_id();
        return 0;
    }
    
    class 默认权限为私有
    #include <iostream>
    using namespace std;
    
    class Student
    {
        int m_id;
    
    public:
        string m_name;
        void set_id(int a)
        {
            m_id = a;
        }
        void show_id()
        {
            cout << m_id << endl;
        }
    };
    
    int main()
    {
    
        Student stu;
        stu.m_name = "ddd";
        stu.set_id(123);
        // 操作属性
        cout << "stu.m_name : " << stu.m_name << endl;
        stu.show_id();
        return 0;
    }
    

    4. 成员属性设置为私有是很不错的做法!

    成员属性设置为私有是很不错的做法!

    优点1:将所有成员属性设置为私有,可以自己控制读写权限
    优点2:对于写权限,我们可以检测数据的有效性

    二. 构造函数

    c++利用了构造函数析构函数解决对象实例化问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。

    • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
    • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。

    1. 构造函数

    构造函数语法:类名(){}

    1. 构造函数,没有返回值也不写void
    2. 函数名称与类名相同
    3. 构造函数可以有参数,因此可以发生重载
    #include <iostream>
    using namespace std;
    
    class Student
    {
    public:
        Student(string name,int id)
        {
            m_name = name;
            m_id = id;
        }
        void show_info()
        {
            cout<< m_name <<endl;
            cout<< m_id <<endl;
        }
    private:
        string m_name;
        int m_id;
    };
    
    int main()
    {
    
        Student stu("anny",7);
        stu.show_info();
    
        Student stu2("haha",18);
        stu.show_info();
        stu2.show_info();
        return 0;
    }
      
    

    2. 构造函数分类

    两种分类方式:

    按参数分为: 有参构造和无参构造
    按类型分为: 普通构造和拷贝构造
    

    三种调用方式:

    • 括号法 Person p1(10);
    • 显示法 Person p2 = Person(10);
    • 隐式转换法 Person p4 = 10;

    注意:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        //无参(默认)构造函数
        Person()
        {
            cout << "无参构造函数!" << endl;
        }
        //有参构造函数
        Person(int a)
        {
            age = a;
            cout << "有参构造函数!" << endl;
        }
    
    public:
        int age;
    };
    
    int main()
    {
        // 1 调用无参构造函数
        Person p; //调用无参构造函数
    
        // 2.1  括号法,常用
        Person p1(10);
        //注意:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明
        // Person p2();××××错!!!!!!!!!××××
    
        // 2.2 显式法
        Person p2 = Person(10);
    
        // 2.3 隐式转换法
        Person p4 = 10; 
    
        return 0;
    }
    

    3. 拷贝构造函数

    拷贝构造函数就是用一个实例来构造另一个实例, 是一门克隆技术

    注意: 拷贝构造函数要使用常量引用
    如果不写拷贝构造函数, C++也会自动生成一个拷贝构造函数, 调用时会直接克隆, 而且是浅拷贝!!!

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        //有参构造函数
        Person(int a)
        {
            age = a;
        }
        Person(const Person &a_person)
        {
            age = a_person.age + 10;
            cout << "拷贝构造函数!" << endl;
            cout << "克隆人的诞生!" << endl;
        }
    
    public:
        int age;
    };
    
    int main()
    {
    
        Person p1(10);
    
        Person p2 = Person(p1);
        cout << p2.age << endl;
        return 0;
    }
    

    4. 解决拷贝构造函数的"浅拷贝"问题必须收到创建拷贝构造函数

    三. 构造函数的简写

    C++提供了初始化语法,来用形参初始化属性
    语法:Person(int a, int b, int c) : m_A(a), m_B(b), m_C(c) {}

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        Person(int a, int b, int c) : m_A(a), m_B(b), m_C(c) {}
        void PrintPerson() {
            cout << "mA:" << m_A << endl;
            cout << "mB:" << m_B << endl;
            cout << "mC:" << m_C << endl;
        }
    
    private:
        int m_A;
        int m_B;
        int m_C;
    };
    
    int main()
    {
        Person p1(10, 20, 30);
        p1.PrintPerson();
        return 0;
    }
    

    四. 析构函数

    • 程序在实例化对象时候会自动调用构造,无须手动调用,而且只会调用一次
    #include <iostream>
    using namespace std;
    
    class Student
    {
    public:
        Student(string name,int id)
        {
            m_name = name;
            m_id = id;
        }
        ~Student()
        {
            cout << "析构函数执行!"<<endl;
        }
        void show_info()
        {
            cout<< m_name <<endl;
            cout<< m_id <<endl;
        }
    private:
        string m_name;
        int m_id;
    };
    
    int main()
    {
        Student stu("anny",7);
        stu.show_info();
    }
    

    五. 类属性和类方法

    1. 静态成员(类属性)

    静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

    2. 类属性

    • 静态成员参数
      • 所有对象共享同一份数据
      • 在编译阶段分配内存
      • 类内声明,类外初始化

    注意: 类属性要 : 类内声明,类外初始化

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        static int m_A;
        void show_a()
        {
            cout << m_A << endl;
        }
    };
    // 必须在外面初始化变量
    int Person::m_A = 10;
    int main()
    {
        Person p1;
        p1.m_A = 100;
        p1.show_a();
    
        Person p2;
        p2.show_a();
        return 0;
    }
    

    3. 类方法

    静态成员函数

    • 所有对象共享同一个函数
    • 静态成员函数只能访问静态成员变量

    注意: 静态成员函数只能访问静态成员变量

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        static int m_A;
        static void show_a()
        {
            cout << m_A << endl;
        }
    };
    // 必须在外面初始化变量
    int Person::m_A = 10;
    int main()
    {
        Person p1;
        p1.m_A = 100;
        p1.show_a();
    
        Person p2;
        p2.show_a();
        return 0;
    }
    

    非静态的属性和方法就是 : 实例属性/实例方法

    六. C++ this指针

    this指针 是 c++通过提供特殊的对象指针, this指针指向被调用的成员函数所属的对象

    七. 常对象及常函数

    常函数可以认为只读函数
    常对象可以认为只有读权限的对象

    1. 常函数 (创建类时, 可以在类中创建常函数)

    • 成员函数后加const后我们称为这个函数为常函数
    • 常函数内不可以修改成员属性
    • 成员属性声明时加关键字mutable后,在常函数中依然可以修改
    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        int m_A;
        void show_a() const
        {
            cout << "常函数执行," << m_A << endl;
        }
    };
    
    int main()
    {
        Person p1;
        p1.show_a();
    }
    

    2. 常对象 (实例化类时, 可以实例化常对象)

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        Person()
        {
            m_A = 0;
        }
        void show_a() const
        {
            cout << "常函数执行," << m_A << endl;
        }
    
    public:
        int m_A;
    };
    
    int main()
    {
        const Person p1;
        p1.show_a();
    }
    

    3. 常对象只能调用常函数和静态函数, 无法调用成员函数

    • 常对象可以调用类属性, 也能修改它们
    • 常对象只能调用实例属性, 但不能修改它们
    • 常对象只能调用常函数和类方法, 无法调用实例方法
    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        Person(int a)
        {
            this->m_A = a; // 成员属性(实例属性)
        }
        void show_a() const // 常函数
        {
            cout << "常函数执行," << m_A << endl;
        }
    
        static void show_b() //静态方法(类方法)
        {
            cout << "静态函数执行," << m_B << endl;
        }
        void show_c() // 实例方法
        {
            cout << "成员函数执行," << m_A << endl;
        }
    
    public:
        int m_A;
        static int m_B; // 静态参数 (类属性)
    };
    int Person::m_B = 200; //静态参数赋值 (类属性赋值)
    int main()
    {
        const Person p1 = Person(100);
        // p1.m_A = 200;  常对象无法修改实例属性
        cout << p1.m_A << endl; //常对象可以访问实例属性
        p1.m_B = 300;           //常对象可以修改类属性
        cout << p1.m_B << endl; //常对象可以访问类属性
        p1.show_a();            //常对象可以调用常函数
        p1.show_b();            //常对象可以调用类方法
        // p1.show_c(); //常对象无法调用成员方法(实例方法)
    }
    

    八. 运算符重载 (魔法)

    1. 以 + 的重载为例

    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        Person(){};
        Person(int a, int b)
        {
            this->m_A = a;
            this->m_B = b;
        }
        //成员函数实现 + 号运算符重载
        Person operator+(const Person &p)
        {
            Person temp;
            temp.m_A = this->m_A + p.m_A;
            temp.m_B = this->m_B + p.m_B;
            return temp;
        }
    
    public:
        int m_A;
        int m_B;
    };
    int main()
    {
        Person p1(3, 4);
    
        Person p2(7, 8);
    
        Person p3 = p1 + p2;
    
        cout << p3.m_A << endl;
        cout << p3.m_B << endl;
    }
    

    值得一提的时, 操作符方法是可以根据不同的传参进行重载的

    2. C++ 可操作的运算符重载

    下面是可重载的运算符列表:

    使用方法参考:

    C++运算符重载 https://blog.csdn.net/bzxb355/article/details/124114746

    九. 继承

    1. 继承的基本语法

    //公共页面
    class BasePage
    {
    public:
        void header()
        {
            cout << "首页、公开课、登录、注册...(公共头部)" << endl;
        }
    
        void footer()
        {
            cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
        }
        void left()
        {
            cout << "Java,Python,C++...(公共分类列表)" << endl;
        }
    
    };
    
    //Java页面
    class Java : public BasePage
    {
    public:
        void content()
        {
            cout << "JAVA学科视频" << endl;
        }
    };
    //Python页面
    class Python : public BasePage
    {
    public:
        void content()
        {
            cout << "Python学科视频" << endl;
        }
    };
    //C++页面
    class CPP : public BasePage
    {
    public:
        void content()
        {
            cout << "C++学科视频" << endl;
        }
    };
    
    void test01()
    {
        //Java页面
        cout << "Java下载视频页面如下: " << endl;
        Java ja;
        ja.header();
        ja.footer();
        ja.left();
        ja.content();
        cout << "--------------------" << endl;
    
        //Python页面
        cout << "Python下载视频页面如下: " << endl;
        Python py;
        py.header();
        py.footer();
        py.left();
        py.content();
        cout << "--------------------" << endl;
    
        //C++页面
        cout << "C++下载视频页面如下: " << endl;
        CPP cp;
        cp.header();
        cp.footer();
        cp.left();
        cp.content();
    
    
    }
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    }
    

    2. 继承的权限

    • public : 可以被子类访问
    • protected : 可以被子类访问
    • private : 只能被本类访问,不能被子类访问;

    3. 三种继承方式

    4. 公有继承

    公有继承的特点:

    • 子类继承父类后, 不会修改
      public 成员,protected 成员,private 成员的访问属性在派生类中不变,
      继续是:public, protected, private
    • 子类的子类继承时还能按照这些权限往下继承
    #include <iostream>
    using namespace std;
    
    class Base1
    {
    public:
        int m_A = 666;
    
    protected:
        int m_B = 888;
    
    private:
        int m_C = 999;
    };
    
    //公共继承
    class Son1 : public Base1
    {
    public:
        void func()
        {
            cout << "Son m_A : " << m_A << endl; //可访问 public权限
            cout << "Son m_B : " << m_B << endl; //可访问 protected权限
            // cout << "m_C" << m_C << endl; // m_C; //不可访问
        }
    };
    
    int main()
    {
        Son1 s1;
        s1.func();
    
        return 0;
    }
    

    5. 保护继承

    保护继承的特点:

    • 子类继承父类后, 会修改
      public 成员,protected 成员,private 成员的访问属性权限变为:protected, protected, private
    • 因为把父类的public 修改为了protected, 所以无法再外部访问了
    • 子类的子类还会继承这些protected属性, 还是只能内部访问, 无法外部访问
    #include <iostream>
    using namespace std;
    
    class Base2
    {
    public:
        int m_A = 666;
    
    protected:
        int m_B = 888;
    
    private:
        int m_C = 999;
    };
    
    //保护继承
    class Son2 : protected Base2
    {
    public:
        void func()
        {
            cout << "Son m_A : " << m_A << endl; //可访问 protected权限
            cout << "Son m_B : " << m_B << endl; //可访问 protected权限
            // cout << "m_C" << m_C << endl; // m_C; //不可访问
        }
    };
    
    class GrandSon : Son2
    {
    public:
        void func()
        {
            cout << "GrandSon m_A : " << m_A << endl; //可访问 protected权限
            cout << "GrandSon m_B : " << m_B << endl; //可访问 protected权限
            // cout << "m_C" << m_C << endl; // m_C; //不可访问
        }
    };
    
    int main()
    {
        Son2 s2;
        s2.func();
        // cout << s2.m_A << endl; // 不可访问,因为m_A已经是protect权限了
        GrandSon ss2;
        ss2.func();
        // cout << ss2.m_A << endl; // 不可访问,因为m_A已经是protect权限了
        return 0;
    }
    

    6. 私有继承

    保护继承的特点:

    • 子类继承父类后, 会修改
      public 成员,protected 成员,private 成员的访问属性权限变为:private, private, private
    • 因为把父类的public 修改为了private, 所以无法再外部访问了, 而且无法再继承下去
    • 子类的子类不会继承这些private属性了, 无法访问
    #include <iostream>
    using namespace std;
    
    class Base3
    {
    public:
        int m_A = 666;
    
    protected:
        int m_B = 888;
    
    private:
        int m_C = 999;
    };
    
    //私有继承
    class Son3 : private Base3
    {
    public:
        void func()
        {
            cout << "Son m_A : " << m_A << endl; //可访问 private权限
            cout << "Son m_B : " << m_B << endl; //可访问 private权限
            // cout << "m_C" << m_C << endl; // m_C; //不可访问
        }
    };
    
    class GrandSon : Son3
    {
    public:
        void func()
        {
            // Son3是私有继承,所以继承Son3的属性在GrandSon中都无法访问到
        }
    };
    
    int main()
    {
        Son3 s3;
        s3.func();
        // cout << s2.m_A << endl; // 不可访问,因为m_A已经是private权限了
        GrandSon ss3;
        ss3.func();
        // cout << ss2.m_A << endl; // 不可访问,因为根本没继承
        return 0;
    }
    

    其实 : 父类中私有成员也是被子类继承下去了,只是由编译器给隐藏后访问不到

    7. 子类新建属性和父类重名问题

    当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?

    • 访问子类同名成员 直接访问即可
    • 访问父类同名成员 需要加作用域
    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
        Base()
        {
            m_A = 100;
        }
    
        void func()
        {
            cout << "Base - func()调用" << endl;
        }
    
        void func(int a)
        {
            cout << "Base - func(int a)调用" << endl;
        }
    
    public:
        int m_A;
    };
    
    class Son : public Base
    {
    public:
        Son()
        {
            m_A = 200;
        }
    
        //当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
        //如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
        void func()
        {
            cout << "Son - func()调用" << endl;
        }
    
    public:
        int m_A;
    };
    
    int main()
    {
    
        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);
    
        return EXIT_SUCCESS;
    }
    

    十. 多态

    • 假设: 猫猫、狗狗都继承Animal 类型
    • 编写一个函数DoSpeak, 传入泛Animal 类型, 传入猫就是猫叫, 传入狗就是狗叫
    class Animal
    {
    public:
        //Speak函数就是虚函数
        //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
    };
    
    class Cat :public Animal
    {
    public:
        void speak()
        {
            cout << "小猫在说话" << endl;
        }
    };
    
    class Dog :public Animal
    {
    public:
    
        void speak()
        {
            cout << "小狗在说话" << endl;
        }
    
    };
    // 编写一个函数, 传入泛Animal 类型, 传入猫就是猫叫, 传入狗就是狗叫
    void DoSpeak(Animal & animal)
    {
        animal.speak();
    }
    
    int main() {
    
        Cat cat;
        DoSpeak(cat);
    
    
        Dog dog;
        DoSpeak(dog);
        return 0;
    }
    

    例: 用多态的风格编写计算器

    C++开发提倡利用多态设计程序架构,因为多态优点很多

    //多态实现
    //抽象计算器类
    //多态优点:代码组织结构清晰,可读性强,利于前期和后期的扩展以及维护
    class AbstractCalculator
    {
    public :
    
        virtual int getResult()
        {
            return 0;
        }
    
        int m_Num1;
        int m_Num2;
    };
    
    //加法计算器
    class AddCalculator :public AbstractCalculator
    {
    public:
        int getResult()
        {
            return m_Num1 + m_Num2;
        }
    };
    
    //减法计算器
    class SubCalculator :public AbstractCalculator
    {
    public:
        int getResult()
        {
            return m_Num1 - m_Num2;
        }
    };
    
    //乘法计算器
    class MulCalculator :public AbstractCalculator
    {
    public:
        int getResult()
        {
            return m_Num1 * m_Num2;
        }
    };
    
    
    void test02()
    {
        //创建加法计算器
        AbstractCalculator *abc = new AddCalculator;
        abc->m_Num1 = 10;
        abc->m_Num2 = 10;
        cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() << endl;
        delete abc;  //用完了记得销毁
    
        //创建减法计算器
        abc = new SubCalculator;
        abc->m_Num1 = 10;
        abc->m_Num2 = 10;
        cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() << endl;
        delete abc;  
    
        //创建乘法计算器
        abc = new MulCalculator;
        abc->m_Num1 = 10;
        abc->m_Num2 = 10;
        cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() << endl;
        delete abc;
    }
    
    int main() {
    
        //test01();
    
        test02();
    
        system("pause");
    
        return 0;
    }
    

    十一. 纯虚函数和抽象类

    在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容

    因此可以将虚函数改为纯虚函数

    纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;

    当类中有了纯虚函数,这个类也称为==抽象类==

    抽象类特点

    • 无法实例化对象
    • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
    #include <iostream>
    using namespace std;
    
    class Toy
    {
    public:
        virtual void show_price() = 0;
        virtual float raise_price(float) = 0;
        virtual void change_name(string) = 0;
        virtual void open() = 0;
        virtual void play() = 0;
        void first_play()
        {
            open();
            play();
        }
    };
    
    class LegoToy : public Toy
    {
    public:
        LegoToy(string name, float price) : m_name(name), m_price(price){};
        void show_price()
        {
            cout << m_price << endl;
        }
        float raise_price(float raise)
        {
            m_price += raise;
            return m_price;
        }
        void change_name(string newname)
        {
            m_name = newname;
        }
        void open()
        {
            cout << "打开玩具 : " << m_name << endl;
        }
    
        void play()
        {
            cout << "开始玩价值" << m_price << "元的" << m_name << endl;
        }
    
    public:
        float m_price = 0.0;
        string m_name = "未知";
    };
    class LiuliuqiuToy : public Toy
    {
    public:
        LiuliuqiuToy(string name, float price) : m_name(name), m_price(price){};
        void show_price()
        {
            cout << m_price << endl;
        }
        float raise_price(float raise)
        {
            cout << "溜溜球不允许涨价" << endl;
            return m_price;
        }
        void change_name(string newname)
        {
            m_name = newname;
        }
        void open()
        {
            cout << "撕开 " << m_name << "的塑料包装!" << endl;
        }
    
        void play()
        {
            cout << "旋转跳跃我闭着眼~~~" << endl;
        }
    
    public:
        float m_price = 0.0;
        string m_name = "未知";
    };
    //业务函数
    void play_toy(Toy &toy)
    {
        toy.first_play();
    }
    int main()
    {
        LegoToy myLego = LegoToy("乐高打字机", 900);
        play_toy(myLego);
        LiuliuqiuToy myllq("五彩LED溜溜球",3);
        play_toy(myllq);
        return EXIT_SUCCESS;
    }
    

    例: 用虚构类 + 多态, 可以实现面向对象的抽象化

    下面的例子中, 我们抽象化了制作饮品的过程,

    当我们创建子类时, 实现了这些过程, 并完成了制作饮品的过程

    //抽象制作饮品
    class AbstractDrinking {
    public:
        //烧水
        virtual void Boil() = 0;
        //冲泡
        virtual void Brew() = 0;
        //倒入杯中
        virtual void PourInCup() = 0;
        //加入辅料
        virtual void PutSomething() = 0;
        //规定流程
        void MakeDrink() {
            Boil();
            Brew();
            PourInCup();
            PutSomething();
        }
    };
    
    //制作咖啡
    class Coffee : public AbstractDrinking {
    public:
        //烧水
        virtual void Boil() {
            cout << "煮农夫山泉!" << endl;
        }
        //冲泡
        virtual void Brew() {
            cout << "冲泡咖啡!" << endl;
        }
        //倒入杯中
        virtual void PourInCup() {
            cout << "将咖啡倒入杯中!" << endl;
        }
        //加入辅料
        virtual void PutSomething() {
            cout << "加入牛奶!" << endl;
        }
    };
    
    //制作茶水
    class Tea : public AbstractDrinking {
    public:
        //烧水
        virtual void Boil() {
            cout << "煮自来水!" << endl;
        }
        //冲泡
        virtual void Brew() {
            cout << "冲泡茶叶!" << endl;
        }
        //倒入杯中
        virtual void PourInCup() {
            cout << "将茶水倒入杯中!" << endl;
        }
        //加入辅料
        virtual void PutSomething() {
            cout << "加入枸杞!" << endl;
        }
    };
    
    //业务函数
    void DoWork(AbstractDrinking* drink) {
        drink->MakeDrink();
        delete drink;
    }
    
    void test01() {
        DoWork(new Coffee);
        cout << "--------------" << endl;
        DoWork(new Tea);
    }
    
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    }
    

    例2: 使用用虚构类虚构元器件 , 组装具体设备时具体实现

    #include<iostream>
    using namespace std;
    
    //抽象CPU类
    class CPU
    {
    public:
        //抽象的计算函数
        virtual void calculate() = 0;
    };
    
    //抽象显卡类
    class VideoCard
    {
    public:
        //抽象的显示函数
        virtual void display() = 0;
    };
    
    //抽象内存条类
    class Memory
    {
    public:
        //抽象的存储函数
        virtual void storage() = 0;
    };
    
    //电脑类
    class Computer
    {
    public:
        Computer(CPU * cpu, VideoCard * vc, Memory * mem)
        {
            m_cpu = cpu;
            m_vc = vc;
            m_mem = mem;
        }
    
        //提供工作的函数
        void work()
        {
            //让零件工作起来,调用接口
            m_cpu->calculate();
    
            m_vc->display();
    
            m_mem->storage();
        }
    
        //提供析构函数 释放3个电脑零件
        ~Computer()
        {
    
            //释放CPU零件
            if (m_cpu != NULL)
            {
                delete m_cpu;
                m_cpu = NULL;
            }
    
            //释放显卡零件
            if (m_vc != NULL)
            {
                delete m_vc;
                m_vc = NULL;
            }
    
            //释放内存条零件
            if (m_mem != NULL)
            {
                delete m_mem;
                m_mem = NULL;
            }
        }
    
    private:
    
        CPU * m_cpu; //CPU的零件指针
        VideoCard * m_vc; //显卡零件指针
        Memory * m_mem; //内存条零件指针
    };
    
    //具体厂商
    //Intel厂商
    class IntelCPU :public CPU
    {
    public:
        virtual void calculate()
        {
            cout << "Intel的CPU开始计算了!" << endl;
        }
    };
    
    class IntelVideoCard :public VideoCard
    {
    public:
        virtual void display()
        {
            cout << "Intel的显卡开始显示了!" << endl;
        }
    };
    
    class IntelMemory :public Memory
    {
    public:
        virtual void storage()
        {
            cout << "Intel的内存条开始存储了!" << endl;
        }
    };
    
    //AMD厂商
    class AMDCPU :public CPU
    {
    public:
        virtual void calculate()
        {
            cout << "AMD的CPU开始计算了!" << endl;
        }
    };
    
    class AMDVideoCard :public VideoCard
    {
    public:
        virtual void display()
        {
            cout << "AMD的显卡开始显示了!" << endl;
        }
    };
    
    class AMDMemory :public Memory
    {
    public:
        virtual void storage()
        {
            cout << "AMD的内存条开始存储了!" << endl;
        }
    };
    
    
    void test01()
    {
        //第一台电脑零件
        CPU * intelCpu = new IntelCPU;
        VideoCard * intelCard = new IntelVideoCard;
        Memory * intelMem = new IntelMemory;
    
        cout << "第一台电脑开始工作:" << endl;
        //创建第一台电脑
        Computer * computer1 = new Computer(intelCpu, intelCard, intelMem);
        computer1->work();
        delete computer1;
    
        cout << "-----------------------" << endl;
        cout << "第二台电脑开始工作:" << endl;
        //第二台电脑组装
        Computer * computer2 = new Computer(new LenovoCPU, new LenovoVideoCard, new LenovoMemory);;
        computer2->work();
        delete computer2;
    
        cout << "-----------------------" << endl;
        cout << "第三台电脑开始工作:" << endl;
        //第三台电脑组装
        Computer * computer3 = new Computer(new LenovoCPU, new IntelVideoCard, new LenovoMemory);;
        computer3->work();
        delete computer3;
    }
    

    相关文章

      网友评论

          本文标题:C++基础一文通(四)面向对象

          本文链接:https://www.haomeiwen.com/subject/evyqirtx.html