C++多态案例---计算器类

本文通过实例展示了如何使用C++的普通写法和多态实现计算器类,重点突出了多态在代码组织、可读性和扩展性方面的优势,强调了在实际开发中遵循开闭原则的重要性。

我们要实现的是分别利用普通写法和多态去实现一个能让两个数进行运算的计算器类 

从而比较多态相比普通写法的优势,在实际的c++开发中是非常提倡利用多态去设计程序架构!

先是普通写法的:

#include <iostream>
using namespace std;

class Calculator
{

public:
     int  docalculator(string oper)
    {
        if(oper=="+")
        {
            return m_num1+m_num2;
        }
        else if(oper=="-")
        {
            return m_num1-m_num2;
        }
        else if(oper=="*")
        {
            return m_num1*m_num2;
        }
    }
    int m_num1;
    int m_num2;

};

void test01()
{
    Calculator  c;
    c.m_num1=10;
    c.m_num2=10;
    cout<<c.m_num1<<"+"<<c.m_num2<<"= "<<c.docalculator("+")<<endl;
    cout<<c.m_num1<<"-"<<c.m_num2<<"= "<<c.docalculator("-")<<endl;
    cout<<c.m_num1<<"*"<<c.m_num2<<"= "<<c.docalculator("*")<<endl;
}
int main()
{
    test01();
    system("pause");
    return 0;
}

普通的写法,没能很好的体现开闭原则,因为如果想扩展新的功能则需要修改类里的源码,而在实际开发中提倡开闭原则,对扩展开放,对修改关闭。

下面我们来看看利用多态的写法:

#include <iostream>
using namespace std;
//先创建一个基类
class Abstractcalculate
{
public:
    virtual int  docalculate()
    {
        return 0;
    }
    int m_num1;
    int m_num2;

};

//下面一一创建自己需要的
//加法类
class  Addcalculate:public Abstractcalculate
{
    public:
    virtual int  docalculate()
    {
        return m_num1+m_num2;
    }
};

//减法类
class  Subcalculate:public Abstractcalculate
{
    public:
    virtual int  docalculate()
    {
        return m_num1-m_num2;
    }
};

//乘法类
class  Mulcalculate:public Abstractcalculate
{
    public:
    virtual int  docalculate()
    {
        return m_num1*m_num2;
    }
};

void test02()
{
    //实现加法,多态使用条件是父类的指针或对象指向子类,这次我们用指针
    Abstractcalculate  *abc=new Addcalculate; //创建一个父类的指针abc去指向新开辟的addcalculate类的空间
    abc->m_num1=100;
    abc->m_num2=100;
    cout<<abc->m_num1<<"+"<< abc->m_num2<<"="<<abc->docalculate()<<endl;
    //此时自然会执行加法类的函数
    delete abc;   //由于是在堆区开辟的一片空间,用完了了要手动释放
    //
    abc=new Subcalculate;  
    //指针指向的空间被删除了,但是指针还在,而且就是Abstractcalculate类型的
    abc->m_num1=100;
    abc->m_num2=100;
    cout<<abc->m_num1<<"-"<< abc->m_num2<<"="<<abc->docalculate()<<endl;
    delete abc;
    abc=new Mulcalculate;
    abc->m_num1=100;
    abc->m_num2=100;
    cout<<abc->m_num1<<"*"<< abc->m_num2<<"="<<abc->docalculate()<<endl;
    delete abc;
}

int main()
{
 
    test02();
    system("pause");
    return 0;
}

可以感受到多态的好处:
1、组织结构清晰
2、可读性强(以后的开发中,我们可能写代码的时候都没有读代码多,因为一个项目往往是多个人一起做的,所以我们就需要去大量阅读别人的代码,此时如果一个人的代码你一看就读懂了,要知道不是你厉害,大多数时候是写代码的人厉害,因为他能够写的通俗易懂让你看懂)
3、对于前期和后期的拓展和维护性高  很好的体现了开闭原则!

通过此案例,希望大家能切实体会到多态带来的好处,在以后的学习中多多使用多态!
 

### 关于C++多态性的练习题与示例 #### 什么是C++多态性? C++多态性是指通过基接口调用派生方法的能力,这种特性使得程序更加灵活和可扩展。多态可以通过两种方式实现:编译时多态(静态绑定)和运行时多态(动态绑定)。前者主要依赖函数重载和模板[^3],而后者则依靠虚函数机制。 #### 运行时多态的核心要素 为了实现运行时多态,通常需要以下几个条件: 1. 定义一个带有`virtual`关键字的成员函数作为虚函数。 2. 使用指向基的指针或引用操作派生对象。 3. 基可以包含纯虚函数来定义抽象,从而强制派生实现特定功能[^2]。 以下是几个典型的多态应用实例: --- #### 示例代码:计算器 此例子展示了如何利用多态创建不同型的运算符行为。 ```cpp #include <iostream> using namespace std; class Operator { public: virtual double calculate(double a, double b) const = 0; // 纯虚函数 }; class Add : public Operator { public: double calculate(double a, double b) const override { return a + b; } }; class Subtract : public Operator { public: double calculate(double a, double b) const override { return a - b; } }; void performCalculation(const Operator& op, double num1, double num2) { cout << "Result: " << op.calculate(num1, num2) << endl; } int main() { Add addOp; Subtract subOp; performCalculation(addOp, 5, 3); // 输出 Result: 8 performCalculation(subOp, 5, 3); // 输出 Result: 2 return 0; } ``` 上述代码中,`Operator`是一个抽象,其派生实现了具体的计算逻辑。通过传递不同的具体型到通用函数`performCalculation`中,体现了多态的作用。 --- #### 示例代码:制作饮品 另一个经典案例涉及模拟咖啡店场景下的饮料制备过程。 ```cpp #include <iostream> using namespace std; // 抽象基 Beverage class Beverage { protected: string description = "Unknown Beverage"; public: virtual ~Beverage() {} string getDescription() const { return description; } virtual double cost() const = 0; // 纯虚函数 }; // 具体产品 HouseBlendCoffee class HouseBlendCoffee : public Beverage { public: HouseBlendCoffee() { this->description = "House Blend Coffee"; } double cost() const override { return 0.89; } // 覆盖成本 }; // 具体产品 Espresso class Espresso : public Beverage { public: Espresso() { this->description = "Espresso"; } double cost() const override { return 1.99; } }; void prepareOrder(Beverage* beverage) { cout << "Preparing order for " << beverage->getDescription() << ", Cost: $" << beverage->cost() << endl; } int main() { Beverage* coffee = new HouseBlendCoffee(); prepareOrder(coffee); Beverage* espresso = new Espresso(); prepareOrder(espresso); delete coffee; delete espresso; return 0; } ``` 在这个例子中,我们看到即使不知道确切的对象型,也可以安全地调用它们各自的`cost()`方法并获得相应结果。 --- #### 注意事项 当处理含有虚拟表(vtable)支持的多态结构时,请务必注意以下几点: - 如果计划销毁由基指针管理的生命期,则应声明虚析构函数以防止内存泄漏。 - 型转换需谨慎执行;建议优先考虑使用`dynamic_cast`而非其他形式强转[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值