多态练习/抽象函数
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;
}