IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++(七)——多态 -> 正文阅读

[C++知识库]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;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:33:09  更:2022-03-13 21:35:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:36:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码