多态练习/抽象函数

2021-08-02  本文已影响0人  Sheik

环境:ide:Mac+clion

视频链接:
https://www.bilibili.com/video/BV1Hb411Y7E5?p=5

普通写法和多态写法实现计算器

这里涉及到一个开闭原则:对扩展开放,对修改关闭。
传统的写法:

class Caculator{
public:
    Caculator(int num1,int num2):m_Number1(num1),m_Number2(num2){
    }

    int getResult(char oper){
        switch (oper) {
            case '+':
                return m_Number1 + m_Number2;
                break;
            case '-':
                return m_Number1 - m_Number2;
                break;
            case '*':
                return m_Number1 * m_Number2;
                break;
            default:
                break;
        }
    }

private:
    int m_Number1;
    int m_Number2;

};

void test(){
    Caculator caculator(1,2);
    cout << caculator.getResult('+')<< endl;//3
    cout << caculator.getResult('-')<< endl;//-1
    cout << caculator.getResult('*')<< endl;//2
}

通过多态的方式实现:

//计算器的基类
class AbstractCaculator {
public :
    virtual int getResult() {};
    int m_Num1;
    int m_Num2;
};

//加法
class AddCaculator : public AbstractCaculator {
public:
    int getResult() {
        return m_Num1 + m_Num2;
    }
};

//减法
class SubCaculator : public AbstractCaculator {
public:
    int getResult() {
        return m_Num1 - m_Num2;
    }
};

//乘法
class MultiCaculator : public AbstractCaculator {
public:
    int getResult() {
        return m_Num1 * m_Num2;
    }
};

void test1() {
    AbstractCaculator *caculator = new AddCaculator();
    caculator->m_Num1 = 1;
    caculator->m_Num2 = 2;
    cout << caculator->getResult() << endl;//3
    delete caculator;
    caculator = new SubCaculator;
    caculator->m_Num1 = 4;
    caculator->m_Num2 = 2;
    cout << caculator->getResult() << endl;//2
    delete caculator;
    caculator = new MultiCaculator();
    caculator->m_Num1 = 4;
    caculator->m_Num2 = 2;
    cout << caculator->getResult() << endl;//8
    delete caculator;
}

抽象类和纯虚函数:

只要有一个纯虚函数的类就是抽象类。抽象类无法实例化对象,子类必须重写纯虚函数,否则也是抽象类。
纯虚函数语法:virtual 返回值 函数名() = 0;

//只要有一个纯虚函数的类就是抽象类。抽象类不能被实例化。
class Base{//这是一个抽象类,不能被实例化。继承该类的子类需要实现纯虚函数。否则也是抽象函数
public:
    virtual  void func()=0;//这就是纯虚函数的写法。
};

class Son:public Base{
public:
    void func(){
        cout << "子类被func被调用"<<endl;
    }
};

void test(){
    //Base base;//error: variable type 'Base' is an abstract class
   // Base * base = new Base();//error: allocating an object of abstract class type 'Base'
   Son son;
   son.func();//输出:子类被func被调用
}

虚析构函数 和纯析构函数
适用场景:如果子类的属性开辟在堆中,那么父类无法释放子类中的内存。
都是用来解决子类属性申请在堆空间。无法释放内存的问题。

class Animal{
public:
    virtual void speak() = 0;
//    virtual  ~Animal(){
//        cout << "动物基类的析构函数!"<<endl;
//    }
    virtual ~Animal() = 0;

};

class Cat:public Animal{
public:
    Cat(string name){
        cout << "猫的构造函数."<<endl;
        m_Name = new string(name);
    }
    void speak(){
        cout << "猫在讲话."<<endl;
    }

    ~Cat(){
        if (m_Name != NULL){
            delete m_Name;
            m_Name = NULL;
        }
        cout << "猫析构函数执行."<<endl;
    }
    string *m_Name;
};
Animal::~Animal() {
    cout << "动物基类的析构函数!"<<endl;
}

void test(){
    Animal *cat = new Cat("Tom");
    cat->speak();
    delete cat;
}
上一篇下一篇

猜你喜欢

热点阅读