c++ 基础知识-类和对象-多态2
1.多态-纯虚函数和抽象类
#include <iostream>
#include <string>
using namespace std;
//抽象类
//抽象类特点:
//1.无法实例化对象
//2.子类必须重写抽象类中的纯虚函数,否则也属于抽象类
class AbstractCalculator
{
public:
//虚构函数
//后缀等于0,纯虚函数,语法 virtual 返回值类型 函数名 (参数列表) = 0
virtual int getResult() = 0;
int m_a;
int m_b;
};
class Addition:public AbstractCalculator
{
public:
//重写父类中函数,函数名称、返回值类型、参数列表全部一致
int getResult()
{
return m_a + m_b;
}
};
class Subtraction:public AbstractCalculator
{
public:
int getResult()
{
return m_a - m_b;
}
};
//function
int doCalculate(AbstractCalculator &calculator)
{
return calculator.getResult();
}
void fun()
{
Addition add;
add.m_a = 10;
add.m_b = 190;
cout<<"Addition result is "<<doCalculate(add)<<endl;
Subtraction subtract;
subtract.m_a = 10;
subtract.m_b = 190;
cout<<"Subtraction result is "<<doCalculate(subtract)<<endl;
}
int main()
{
fun();
return 0;
}
2.多态-实际应用案例
#include <iostream>
#include <string>
using namespace std;
//抽象类
//抽象类特点:
//1.无法实例化对象
//2.子类必须重写抽象类中的纯虚函数,否则也属于抽象类
class DoDrinks
{
public:
//虚构函数
//后缀等于0,纯虚函数,语法 virtual 返回值类型 函数名 (参数列表) = 0
//first step
void pourWater()
{
cout<<"Pouring water !!!"<<endl;
}
//second step
virtual void foamMaterial() = 0;
//third step
void intoCup()
{
cout<<"Pour it into a cup!!!"<<endl;
}
//forth step
virtual void foamAddMaterial() = 0;
string m_material;
string m_add_material;
};
class DoCoffee:public DoDrinks
{
public:
//重写父类中函数,函数名称、返回值类型、参数列表全部一致
//second step
void foamMaterial()
{
cout<<"foam material "<<m_material<<endl;
}
//forth step
void foamAddMaterial()
{
cout<<"foam addition material "<<m_add_material<<endl;
}
};
class DoTea:public DoDrinks
{
public:
//second step
void foamMaterial()
{
cout<<"foam material "<<m_material<<endl;
}
//forth step
void foamAddMaterial()
{
cout<<"foam addition material "<<m_add_material<<endl;
}
};
//function
void doDrink(DoDrinks &drink)
{
//1
drink.pourWater();
//2
drink.foamMaterial();
//3
drink.intoCup();
//4
drink.foamAddMaterial();
}
void fun()
{
DoCoffee coffee;
coffee.m_material = "coffee";
coffee.m_add_material = "milk and sugar";
doDrink(coffee);
cout<<"=================="<<endl;
DoTea tea;
tea.m_material = "tea";
tea.m_add_material = "lemon";
doDrink(tea);
}
int main()
{
fun();
return 0;
}
3.虚析构和纯虚析构
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方法:将父类中的析构函数改为虚析构和纯虚析构函数
虚析构和纯虚析构共性:
可以解决父类指针释放子类对象
都需要有具体的函数实现
虚析构和纯虚析构区别:
如果是纯虚析构,该类属于抽象类,无法实例化对象
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
using namespace std;
//虚析构语法:
//virtual ~类名(){}
//纯虚析构语法:
//virtual ~类名() = 0;
class Base
{
public:
//构造函数
Base();
//虚函数
virtual void speak() = 0;
//虚析构函数
//利用虚析构
virtual ~Base();
//virtual ~Base() = 0;
string *m_Name;
};
class A:public Base
{
public:
//构造函数
A(string name);
void speak()
{
cout<<*m_Name<<" === speaking ! ! ! "<<endl;
}
//虚析构函数
~A();
};
void doSpeak();
void fun();
#endif
#include "test.h"
Base::Base()
{
cout<<"Base === 构造函数"<<endl;
}
//注意虚析构函数的实现不加virtual,只有声明过程加virtual
Base::~Base()
{
cout<<"Base === 析构函数1"<<endl;
if (m_Name != NULL)
{
cout<<"Base === 析构函数2"<<endl;
delete m_Name;
m_Name = NULL;
}
}
A::A(string name)
{
m_Name = new string(name);
cout<<*m_Name<<" === 构造函数"<<endl;
}
A::~A()
{
if (m_Name != NULL)
{
cout<<*m_Name<<" === 析构函数"<<endl;
delete m_Name;
m_Name = NULL;
}
}
void doSpeak()
{
Base *base = new A("aaaa");
base->speak();
delete base;
//输出1
//Base === 构造函数
//aaaa === 构造函数
// aaaa === speaking ! ! !
// Base === 析构函数
//输出2
//Base === 构造函数
//aaaa === 构造函数
//aaaa === speaking ! ! !
//aaaa === 析构函数
//Base === 析构函数1
}
void fun()
{
doSpeak();
//
}
4.多态-实际应用案例
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
using namespace std;
//实现计算机
//CPU
class CPU
{
public:
//抽象计算函数
virtual void calculate() = 0;
};
//VideoCard
class VideoCard
{
public:
//抽象显示函数
virtual void display() = 0;
};
//Memory
class Memory
{
public:
//抽象显示函数
virtual void storage() = 0;
};
//具体零件厂商
//CPU
class IntelCpu:public CPU
{
public:
void calculate();
};
class LenovoCpu:public CPU
{
public:
void calculate();
};
//VideoCard
class IntelVideoCard:public VideoCard
{
public:
void display();
};
class LenovoVideoCard:public VideoCard
{
public:
void display();
};
//Memory
class IntelMemory:public Memory
{
public:
void storage();
};
class LenovoMemory:public Memory
{
public:
void storage();
};
class Computer
{
public:
//构造函数中传入三个零件指针
Computer(CPU *cpu,VideoCard *vc,Memory *mem);
//析构函数释放三个零件指针
~Computer();
//调用各部件工作
void work();
private:
//私有类指针
CPU *m_cpu;
VideoCard *m_vc;
Memory *m_mem;
};
void fun();
#endif
#include "test.h"
void IntelCpu::calculate()
{
cout<<"IntelCpu calculate!"<<endl;
}
void LenovoCpu::calculate()
{
cout<<"LenovoCpu calculate!"<<endl;
}
void IntelVideoCard::display()
{
cout<<"IntelVideoCard display!"<<endl;
}
void LenovoVideoCard::display()
{
cout<<"LenovoVideoCard display!"<<endl;
}
void IntelMemory::storage()
{
cout<<"IntelMemory storage!"<<endl;
}
void LenovoMemory::storage()
{
cout<<"LenovoMemory storage!"<<endl;
}
Computer::Computer(CPU *cpu,VideoCard *vc,Memory *mem)
{
m_cpu = cpu;
m_vc = vc;
m_mem = mem;
}
Computer::~Computer()
{
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;
}
}
void Computer::work()
{
m_cpu->calculate();
m_vc->display();
m_mem->storage();
}
void fun()
{
cout<<"===first===!!!"<<endl;
IntelCpu *intelCpu = new IntelCpu;
IntelVideoCard *intelVc = new IntelVideoCard;
IntelMemory *intelMem = new IntelMemory;
Computer *com1 = new Computer(intelCpu,intelVc,intelMem);
com1->work();
delete com1;//释放内存
cout<<"===second===!!!"<<endl;
Computer *com2 = new Computer(new LenovoCpu,new LenovoVideoCard,new LenovoMemory);
com2->work();
delete com2;
cout<<"===third===!!!"<<endl;
Computer *com3 = new Computer(new LenovoCpu,new IntelVideoCard,new LenovoMemory);
com3->work();
delete com3;
}