多态,文件操作

多态

#include<iostream>
#include <string>
using namespace std;
//多态是C++面向对象三大特性之-
//多态分为两类
//●静态多态 : 函数重载和运算符重载属于静态多态,复用函数名
//●动态多态 : 派生类和虚函数实现运行时多态
//静态多态和动态多态区别 :
//●静态多态的函数地址早绑定 - 编译阶段确定函数地址
//●动态多态的函数地址晚绑定 - 运行阶段确定函数地址
//下面通过案例进行讲解多态

class Animal{
public:
	virtual void speak(){
		cout << "动物在说话" << endl;

	}
};
class Cat :public Animal{
public :
	 void speak(){
		cout << "小猫在说话" << endl;
	}
};
//执行函数
//地址早绑定,在编译阶段就绑定了地址
//如果想执行让猫说话就不能早绑定:加virtual

//动态多态条件:
//必须有继承
//子类重写父类中虚函数

//多态使用
//父类的指针或者引用 执行子类对象
void doSpeak(Animal &animal)
{
	animal.speak();
}
void test()
{
	Cat cat;
	doSpeak(cat);
}
int main()
{
	test();
	system("pause");
}

多态原理

#include<iostream>
#include <string>
using namespace std;
//多态是C++面向对象三大特性之-
//多态分为两类
//●静态多态 : 函数重载和运算符重载属于静态多态,复用函数名
//●动态多态 : 派生类和虚函数实现运行时多态
//静态多态和动态多态区别 :
//●静态多态的函数地址早绑定 - 编译阶段确定函数地址
//●动态多态的函数地址晚绑定 - 运行阶段确定函数地址
//下面通过案例进行讲解多态

class Animal{
public:
	virtual void speak(){
		cout << "动物在说话" << endl;

	}
};
class Cat :public Animal{
public :
	 void speak(){
		cout << "小猫在说话" << endl;
	}
};

//执行函数
//地址早绑定,在编译阶段就绑定了地址
//如果想执行让猫说话就不能早绑定:加virtual

//动态多态条件:
//必须有继承
//子类重写父类中虚函数

//多态使用
//父类的指针或者引用 执行子类对象

void doSpeak(Animal &animal)//Animal &animal =cat ;//当父类的指针或者指向子类对象时候,发生多态
{
	animal.speak();
}
void test()
{
	Cat cat;
	doSpeak(cat);
	cout << sizeof(Animal);//没加1,加上virtualshi 4,因为是一个指针;

	/*
	vfptr --虚函数指针,指向一个虚(表)函数表  vftable  表内记录虚函数的地址
	v     --virtual                          &Animal::speak
	f     --function 
	ptr   --pointer

	当子类重写父类虚函数

	子类中的虚函数表 内部 会替换成 子类的虚函数地址

	*/   
}
int main()
{
	test();
	system("pause");
}

计算器

#include<iostream>
#include <string>
using namespace std;

 //分别利用普通写法和多态技术实现计算器


//普通写法
class Calculator
{
public:
	int getResult(string oper)
	{
		if (oper == "+")
		{
			return n_Num1 + n_Num2;
		}
		else if (oper == "-")
		{
			return n_Num1 - n_Num2;
		}
		else if (oper == "*")
		{
			return n_Num1 * n_Num2;
		}
		else if (oper == "/")
		{
			return n_Num1 / n_Num2;
		}
	}

	int n_Num1;
	int n_Num2;
};

void test()
{
	Calculator ca;
	ca.n_Num1 = 10;
	ca.n_Num2 = 20;
	cout << ca.n_Num1 << "+" << ca.n_Num2 << "="<<ca.getResult("+")<<endl;

}

//利用多态实现计算器
//实现计算的抽象类
//多态好处:
//1、组织结构清晰
//2、可读性强
//3、便于维护
class AbstractCaculator
{
public:
	virtual int getResult()
	{
		return 0;
	}
	int m_Num1;
	int m_Num2;

};

class add :public AbstractCaculator
{
public:
	int getResult()
	{
		return m_Num1 + m_Num2;
	}
};

void test2()
{
	AbstractCaculator *abc = new add;
	abc->m_Num1 = 10;
	abc->m_Num2 = 10;
	cout << abc->m_Num1 << "+" << abc->m_Num2 << "=" << abc->getResult();
	delete abc;
}
int main()
{
	//test();
	test2();
	system("pause");
}

//纯虚函数
/*
因为基本虚函数都会被重写所以我们把它携程纯虚函数
写法: virtual 返回值类型 函数名 (参数列表)=0;

当类中有了纯虚函数,这个类也是抽象类

抽象类特点:
不可以实例化
抽象类的子类,必须重写父类中的纯虚函数,不然子类也成了抽象类

*/

多态案例制作饮品

 #include<iostream>
#include <string>
using namespace std;

 //多态的案例

class AbstractDringking

{
public:
	//煮水
	virtual void Boil() = 0;
	//冲泡
	virtual void Brew() = 0;
	//倒入杯中
	virtual void PourInCup() = 0;
	//加入辅料
	virtual void BoiPutSomethingl() = 0;
	//制作饮品
	void makeDrink() {
		Boil();
		Brew();
		PourInCup();
		BoiPutSomethingl();
	}
};

class Coffee :public AbstractDringking//子类virtual 是可加可不加的
{
public :
	//煮水
	 void Boil()
	{
		cout << "煮水"<<endl;
	}
	//冲泡
	 void Brew()
	{
		cout << "冲泡" << endl;
	}
	//倒入杯中
	 void PourInCup()
	{
		cout << "倒入杯中" << endl;
	}
	//加入辅料
	 void BoiPutSomethingl()
	{
		cout << "加入辅料" << endl;
	}

};

//制作茶叶
class tea :public AbstractDringking
{
public:
	//煮水
	virtual void Boil()
	{
		cout << "煮水2" << endl;
	}
	//冲泡
	virtual void Brew()
	{
		cout << "冲泡tea" << endl;
	}
	//倒入杯中
	virtual void PourInCup()
	{
		cout << "倒入杯中" << endl;
	}
	//加入辅料
	virtual void BoiPutSomethingl()
	{
		cout << "加入辅料" << endl;
	}

};

void doWork(AbstractDringking *abs)
{
	abs->makeDrink();
	delete abs;
}
void test()
{
	doWork(new Coffee);
	cout << "-----------"<<endl;
	doWork(new tea);

}

int main()
{
	test();
	//test2();
	system("pause");
}

/*
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:
●可以解决父类指针释放子类对象
●都需要有具体的函数实现
虚析构和纯虚析构区别:
●如果是纯虚析构,该类属于抽象类,无法实例化对象

*/

#include<iostream>
#include <string>
using namespace std;

/*
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:
●可以解决父类指针释放子类对象
●都需要有具体的函数实现
虚析构和纯虚析构区别:
●如果是纯虚析构,该类属于抽象类,无法实例化对象

*/

class Animal
{
public:
	Animal()
	{
		cout << "调用Animal构zao" << 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构zao" << endl;
	}
	void speak(){
		cout <<*m_Name<< "小猫在说话";
	}
	~Cat()
	{

		if (m_Name != NULL)
		{
			delete m_Name;
			m_Name = NULL;
		}
		cout << "调用cat析构"<<endl;
	}
	string *m_Name;
};

void test()
{
	Animal *animal  = new Cat("tom");
	animal->speak();
	// 父类指针在析构时候不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄漏]

	delete animal;
}

int main()
{
	test();
	//test2();
	system("pause");
}

小案例

#include<iostream>
#include <string>
using namespace std;

/*
电脑组装

*/

class CPU
{
public:
	//抽象计算机函数
	virtual void calculate() = 0;
};

class VideoCard{

public:
	virtual void display() = 0;

};

class Menory{

public:
	//抽象存储函数
	virtual void storage() = 0;
};

class Computer
{

public :
	Computer(CPU * cpu, VideoCard * vc, Menory *mem)
	{
		m_cpu = cpu;
		m_vc = vc;
		m_mem = mem;
	}
	void work()
	{
		m_cpu->calculate();

		m_vc->display();

		m_mem->storage();
	}
	~Computer(){
		//释放零件
		if (m_cpu != NULL)
		{
			delete m_vc;
			m_vc = NULL;
		}
		if (m_vc != NULL)
		{
			delete m_vc;
			m_vc = NULL;
		}
		if (m_mem != NULL)
		{
			delete m_mem;
			m_mem = NULL;
		}

	}

private:

	CPU *m_cpu;
	VideoCard *m_vc;
	Menory *m_mem;

};

//具体厂商
class IntelCPU :public CPU
{
public:
	void calculate()
	{
		cout << "inter CPU开始工作了" << endl;
	}

};

class IntelVideoCard :public VideoCard
{
public:
	void display()
	{
		cout << "显卡开始工作了"<<endl;
	}

};

class IntelMenory :public Menory
{
public:
	void storage()
	{
		cout << "存储开始工作了" << endl;
	}

};



void test()
{
	CPU * interCPU = new IntelCPU;//这三个没释放
	VideoCard *videocard = new IntelVideoCard;
	Menory * intelmenory = new IntelMenory;

	Computer * computer1 = new Computer(interCPU, videocard, intelmenory);
	computer1->work();
	delete computer1;

}

int main()
{
	test();
	
	system("pause");
}

文件操作

#include<iostream>
#include <string>
#include<fstream>
using namespace std;



//文本读写
/*
void test()
{
	ofstream outFile;
	outFile.open("tang.txt");
	outFile << "123" <<"thgn"<<endl;
	outFile << "321" << "hui" << endl;
	outFile.close();

	ifstream inFile;
	string buf;
	inFile.open("tang.txt");

   while (getline(inFile, buf))
	{
	cout << buf << endl;
	}

	inFile.close();

}
*/
//二进制方式
class person{
public:
	char m_Name[64];
	int m_Age;
};


void test2(){
	
	/*ofstream ofs("person.txt", ios::out | ios::binary);
	person p = { "张三", 18 };
	ofs.write((const char *)&p, sizeof(person));
	ofs.close();*/
	
	
	//读
	ifstream ifs("person.txt", ios::in | ios::binary);
	person p;
	ifs.read((char *)&p, sizeof(p));
	cout << "姓名:" << p.m_Name << "年龄:" << p.m_Age << endl;

	ifs.close();
}
int main()
{
	test2();
	
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值