C++(七)——多态

多态的基本语法

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值