c++随记三(黑马程序员学习笔记)(多态,文件操作)

32、多态分为静态和动态两种。静态多态有函数重载、运算符重载;动态多态是派生类和虚函数实现运行时多态。静态多态的函数地址早绑定,编译阶段确定函数地址,动态多态的函数地址晚绑定,运行阶段确定函数地址。动态多态满足条件:(1)有继承关系;(2)子类重写父类的虚函数。动态多态使用:父类的指针或者引用来指向子类的对象。

重写是指函数返回值类型,函数名,参数列表完全一致。

33、当子类重写了父类的虚函数,那么子类中的虚函数表内部会替换成子类的虚函数地址。

34、纯虚函数语法:virtual 返回值类型 函数名(参数列表)=0;当类中有了纯虚函数,这个类也称为抽象类。抽象类无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类。

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

class Base
{
public:
	//纯虚函数,Base为抽象类
	virtual void func() = 0;
};

class Son:public Base
{
public:
	virtual void func()
	{
		cout << "func函数调用" << endl;
	}
};

void test01()
{
	Base* base = new Son;
	base->func();
}
int main()
{
	test01();
	system("pause");
	return 0;
}

35、多态案例:制作饮品

#include<iostream>
#include<string>
using namespace std;
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 Coffee :public AbstractDrinking
{
	//煮水
	virtual void Boil()
	{
		cout << "煮水" << endl;
	}
	//冲泡
	virtual void Brew()
	{
		cout << "冲泡咖啡" << endl;
	}
	//倒入杯中
	virtual void PourInCup()
	{
		cout << "倒入杯中" << endl;
	}
	//加入辅料
	virtual void PutSomeThing()
	{
		cout << "加入糖和牛奶" << endl;
	}
};
//制作茶叶
class Tea :public AbstractDrinking
{
	//煮水
	virtual void Boil()
	{
		cout << "煮矿泉水" << endl;
	}
	//冲泡
	virtual void Brew()
	{
		cout << "冲泡茶叶" << endl;
	}
	//倒入杯中
	virtual void PourInCup()
	{
		cout << "倒入杯中" << endl;
	}
	//加入辅料
	virtual void PutSomeThing()
	{
		cout << "加入枸杞" << endl;
	}
};
//制作函数
void doWork(AbstractDrinking* abs)//AbstractDrinking *abs = new Coffee
{
	abs->makeDrink();
	delete abs;//释放
}
void test01()
{
	doWork(new Coffee);
	cout << "__________________" << endl;
	doWork(new Tea);
}
int main()
{
	test01();
	system("pause");
	return 0;
}

36、多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法释放子类的析构代码,因此将父类中的析构函数改为虚析构和纯虚析构。有了纯虚析构后,这个类也属于抽象类。

37、C++中对于文件操作需要包含头文件<fstream>。文件类型分为文本文件和二进制文件。ofstream写操作,ifstream读操作,fstream读写操作。

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

void test01()
{
	//写文件
	//1、包含头文件fstream
	//2、创建流对象
	ofstream ofs;
	//3、指定打开方式
	ofs.open("test.txt", ios::out);
	//4、写内容
	ofs << "姓名:张三" << endl;
	ofs << "年龄:18" << endl;
	//5、关闭文件
	ofs.close();

	//读文件
	ifstream ifs;
	ifs.open("test.txt", ios::in);
	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}
	//读数据
	char buf[1024] = { 0 };
	//第一种读取方式
	while (ifs >> buf)
	{
		cout << buf << endl;
	}
	//第二种读取方式
	while (ifs.getline(buf, sizeof(buf)))
	{
		cout << buf << endl;
	}
	//第三种读取方式
	string buf;
	while (getline(ifs, buf))
	{
		cout << buf << endl;
	}
	ifs.close();
	//第四种读取方式
	char c;
	while ((c = ifs.get()) != EOF)
	{
		cout << c;
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

38、对二进制文件打开方式要指定为ios::binary。

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

class Person
{
public:
	char m_Name[64];
	int m_Age;
};
void test01()
{
	//写二进制文件
	ofstream ofs;
	ofs.open("person.txt", ios::out | ios::binary);
	Person p = { "张三",18 };
	//const char *是强转
	ofs.write((const char*)&p, sizeof(Person));
	ofs.close();

	//读二进制文件
	ifstream ifs;
	ifs.open("person.txt", ios::in | ios::binary);
	if (!(ifs.is_open()))
	{
		cout << "文件打开失败" << endl;
		return;
	}
	Person p2;
	ifs.read((char*)&p2, sizeof(Person));
	cout << "姓名" << p2.m_Name << "年龄" << p.m_Age << endl;
	ifs.close();
}
int main()
{
	test01();
	system("pause");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章