多态的基本语法
#include<iostream>
using namespace std;
//动态多态满足条件
//1.有继承关系
//2.子类要重写父类的虚函数,注意重载是函数名相同但参数不同
//重写 函数返回值类型 函数名 参数列表 完全相同
//动态多态的使用
//父类的指针或引用执行子类对象
class Animal {
public:
//虚函数
virtual void speak() {
cout << "动物在说话" << endl;
}
};
class Dog :public Animal{
public:
void speak() {
cout << "汪汪叫" << endl;
}
};
class Cat :public Animal {
public:
void speak() {
cout << "喵喵叫" << endl;
}
};
//地址早绑定,在编译阶段确定函数地址
//如果想执行让猫说话,则函数的地址需要在运行阶段绑定,地址晚绑定
//父类引用指向子类的对象
void doSpeak(Animal &animal) {// Animal &animal = cat;
animal.speak();
}
void test01() {
Cat cat;
Dog dog;
doSpeak(cat);
doSpeak(dog);
}
void test02() {
cout << "sizeof animal = " << sizeof(Animal) << endl;
}
int main() {
//test01();
test02();
return 0;
}
案例1——计算器类
#include<iostream>
#include<cstring>
using namespace std;
class Calculator {
public:
int getResult(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.getResult("+") << endl;
cout << c.m_num1 << "-" << c.m_num2 << "=" << c.getResult("-") << endl;
cout << c.m_num1 << "*" << c.m_num2 << "=" << c.getResult("*") << endl;
}
//利用多态实现计算器
class AbstractCalculator {
public:
virtual int getResult() {
return 0;
}
int m_num1;
int m_num2;
};
class Add :public AbstractCalculator {
public:
int getResult() {
return m_num1 + m_num2;
}
};
class Sub :public AbstractCalculator {
public:
int getResult() {
return m_num1 - m_num2;
}
};
class Mul :public AbstractCalculator {
public:
int getResult() {
return m_num1 * m_num2;
}
};
void test02() {
//多态使用条件
//父类指针或者引用指向子类对象
AbstractCalculator* abc = new Add;
abc->m_num1 = 100;
abc->m_num2 = 100;
cout << abc->m_num1 << " + " << abc->m_num2 << " = " << abc->getResult() << endl;
delete abc;
abc = new Sub;
abc->m_num1 = 100;
abc->m_num2 = 100;
cout << abc->m_num1 << " - " << abc->m_num2 << " = " << abc->getResult() << endl;
delete abc;
abc = new Mul;
abc->m_num1 = 100;
abc->m_num2 = 100;
cout << abc->m_num1 << " * " << abc->m_num2 << " = " << abc->getResult() << endl;
delete abc;
}
int main() {
//test01();
test02();
return 0;
}
纯虚函数和抽象类
#include<iostream>
using namespace std;
class Base {
public:
//纯虚函数
//只要有一个纯虚函数,就是抽象类 无法实例化对象
virtual void func() = 0;
};
class Son:public Base {
public:
//抽象类的子类必须要重写父类中的纯虚函数,否则也属于抽象类
void func() {
cout << "this is son" << endl;
}
};
void test01() {
Base* base = new Son;
base ->func();
delete base;
}
int main() {
test01();
return 0;
}
案例2——制作饮品
#include<iostream>
using namespace std;
//多态案例2 制作饮品
class AbstractDrinking {
public:
//煮水
virtual void Boil() = 0;
//冲泡
virtual void Brew() = 0;
//导入杯中
virtual void PourInCup() = 0;
//加入辅料
virtual void PutSomething() = 0;
void makeDrink() {
Boil();
Brew();
PourInCup();
PutSomething();
}
};
class Cofee :public AbstractDrinking {
public:
void Boil() {
cout << "煮矿泉水" << endl;
}
void Brew() {
cout << "冲咖啡" << endl;
}
void PourInCup() {
cout << "倒入杯中" << endl;
}
void PutSomething() {
cout << "加点糖" << endl;
}
};
//制作茶叶
class Tea :public AbstractDrinking {
public:
void Boil() {
cout << "煮自来水" << endl;
}
void Brew() {
cout << "放茶叶" << endl;
}
void PourInCup() {
cout << "倒入杯中" << endl;
}
void PutSomething() {
cout << "加柠檬" << endl;
}
};
void doWork(AbstractDrinking &abs) {
abs.makeDrink();
}
void test01() {
Cofee c;
Tea t;
doWork(c);
doWork(t);
}
int main() {
test01();
return 0;
}
虚析构和纯虚析构
#include<iostream>
#include<cstring>
using namespace std;
class Animal {
public:
Animal() {
cout << "animal构造函数调用" << endl;
}
//利用虚析构指针可以解决 父类释放子类对象时不干净的问题
/*virtual ~Animal() {
cout << "animal虚析构函数调用" << endl;
}*/
//纯虚析构 需要声明也需要实现
//有纯虚析构函数 也属于抽象类 无法实例化
virtual ~Animal() = 0;
virtual void speak() = 0;
};
Animal::~Animal() {
cout << "animal纯虚析构函数调用" << endl;
}
class Cat :public Animal {
public:
Cat(string name) {
m_name = new string(name);
cout << "cat构造函数调用" << endl;
}
void speak() {
cout << *m_name << "喵喵叫" << endl;
}
~Cat() {
if (m_name != NULL)
delete m_name;
m_name = NULL;
cout << "cat析构函数调用" << endl;
}
string* m_name;
};
void test01() {
Animal* a = new Cat("汤姆");
a->speak();
//父类的指针在析构时 不会调用子类中的析构函数,导致子类如果有堆区属性,会内存泄露。
delete a;
}
int main() {
test01();
return 0;
}
案例3——电脑组装
#include<iostream>
using namespace std;
class Cpu {
public:
virtual void calculator() = 0;
};
class VideoCard {
public:
virtual void display() = 0;
};
class Memory {
public:
virtual void storage() = 0;
};
class Intel :public Cpu, public VideoCard, public Memory{
public:
void calculator() {
cout << "intel cpu正在运行" << endl;
}
void display() {
cout << "intel 显卡正在运行" << endl;
}
void storage() {
cout << "intel 内存正在运行" << endl;
}
};
class Lenovo :public Cpu, public VideoCard, public Memory {
public:
void calculator() {
cout << "lenovo cpu正在运行" << endl;
}
void display() {
cout << "lenovo 显卡正在运行" << endl;
}
void storage() {
cout << "lenovo 内存正在运行" << endl;
}
};
//电脑类
class Computer {
public:
Computer(Cpu *c, VideoCard *v, Memory *m) {
m_c = c;
m_v = v;
m_m = m;
}
void doWork() {
m_c->calculator();
m_v->display();
m_m->storage();
}
~Computer() {
if (m_c != NULL) {
delete m_c;
m_c = NULL;
}
//0x000002dde96fc100 {m_c=0x0000000000000000 <NULL> m_v=0x000002dde96fbb68 {...} m_m=0x000002dde96fc3b0 {...} }
if (m_m != NULL) {
delete m_m;
m_m = NULL;
}
if (m_v != NULL) {
delete m_v;
m_v = NULL;
}
cout << "析构函数已执行" << endl;
}
private:
Cpu* m_c;
VideoCard* m_v;
Memory* m_m;
};
void test01() {
Cpu* c = new Intel;
VideoCard* v = new Intel;
Memory* m = new Intel;
Computer* computer = new Computer(c, v, m);
computer -> doWork();
delete computer;
}
int main() {
test01();
return 0;
}
|