// 初尝多态
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

// 抽象类:
// 至少有一个纯虚函数的类
// 抽象类不能实现对象
class AbstractCaculator // 定义计算器
{
protected: // 使用保护权限（目的是使子类可以访问，而其他类不可访问）
    int a, b;

public:
    void setA(int a) { this->a = a; }
    void setB(int b) { this->b = b; }

public:
    // 扩展功能，让子类去实现
    virtual int getResult() = 0; // 纯虚函数，声明函数并赋值为 0
};

class AddCa : public AbstractCaculator
{
    // 必须要去实现纯虚函数
    int getResult()
    {
        return a + b;
    }
};

class SubCa : public AbstractCaculator
{
    // 必须要去实现纯虚函数
    int getResult()
    {
        return a - b;
    }
};

// 多态的体现:
// 1) 定义函数时，形参的类型为父类对象的指针
// 2) 调用函数时，实参的类型为子类对象的指针
int Result(AbstractCaculator *caculator, int a, int b)
{
    caculator->setA(a);
    caculator->setB(b);
    return caculator->getResult();
}

int main()
{
    // 抽象类型不能去定义对象
    // error: cannot declare variable ‘a1’ to be of abstract type ‘AbstractCaculator’
    // AbstractCaculator a1;

    AddCa *a2 = new AddCa;
    cout << Result(a2, 10, 20) << endl;
    cout << Result(new SubCa, 10, 20) << endl; // new SubCa 返回的是一个临时对象，不需要 delete
    delete a2;
    // delete new SubCa; // error: cannot delete expression of type ‘SubCa’

    return 0;
}
