【C++初学】C++核心编程技术详解(三):多态与文件操作
6. 多态
多态是面向对象的三大特性之一,允许派生类重写基类的虚函数。
6.1 多态的基本概念
示例代码:
class Animal {
public:
virtual void speak() {
cout << "动物在说话" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "小猫在说话" << endl;
}
};
class Dog : public Animal {
public:
void speak() override {
cout << "小狗在说话" << endl;
}
};
void DoSpeak(Animal &animal) {
animal.speak();
}
void test01() {
Cat cat;
DoSpeak(cat);
Dog dog;
DoSpeak(dog);
}
int main() {
test01();
system("pause");
return 0;
}
多态案例:实现计算器类
//普通实现
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;
}
//如果要提供新的运算,需要修改源码
}
public:
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 AddCalculator :public AbstractCalculator
{
public:
int getResult()
{
return m_Num1 + m_Num2;
}
};
//减法计算器
class SubCalculator :public AbstractCalculator
{
public:
int getResult()
{
return m_Num1 - m_Num2;
}
};
//乘法计算器
class MulCalculator :public AbstractCalculator
{
public:
int getResult()
{
return m_Num1 * m_Num2;
}
};
void test02()
{
//创建加法计算器
AbstractCalculator* abc = new AddCalculator;
abc->m_Num1 = 10;
abc->m_Num2 = 10;
cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() <<endl;
delete abc; //用完了记得销毁
//创建减法计算器
abc = new SubCalculator;
abc->m_Num1 = 10;
abc->m_Num2 = 10;
cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() <<endl;
delete abc;
//创建乘法计算器
abc = new MulCalculator;
abc->m_Num1 = 10;
abc->m_Num2 = 10;
cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() <<endl;
delete abc;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
6.2 纯虚函数和抽象类
纯虚函数是抽象类中的一种特殊函数,没有实现。
示例代码:
class Base {
public:
virtual void func() = 0;
};
class Son : public Base {
public:
void func() override {
cout << "func调用" << endl;
}
};
void test01() {
Base *base = new Son;
base->func();
delete base;
}
int main() {
test01();
system("pause");
return 0;
}
6.3 多态案例:制作饮品
示例代码:
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 {
public:
void Boil() override {
cout << "煮农夫山泉!" << endl;
}
void Brew() override {
cout << "冲泡咖啡!" << endl;
}
void PourInCup() override {
cout << "将咖啡倒入杯中!" << endl;
}
void PutSomething() override {
cout << "加入牛奶!" << endl;
}
};
class Tea : public AbstractDrinking {
public:
void Boil() override {
cout << "煮自来水!" << endl;
}
void Brew() override {
cout << "冲泡茶叶!" << endl;
}
void PourInCup() override {
cout << "将茶水倒入杯中!" << endl;
}
void PutSomething() override {
cout << "加入枸杞!" << endl;
}
};
void DoWork(AbstractDrinking* drink) {
drink->MakeDrink();
delete drink;
}
void test01() {
DoWork(new Coffee);
cout << "--------------" << endl;
DoWork(new Tea);
}
int main() {
test01();
system("pause");
return 0;
}
6.4 虚析构和纯虚析构
虚析构函数允许通过基类指针释放派生类对象。
示例代码:
class Animal {
public:
virtual void Speak() = 0;
virtual ~Animal() = 0;
};
Animal::~Animal() {
cout << "Animal 纯虚析构函数调用!" << endl;
}
class Cat : public Animal {
public:
Cat(string name) {
m_Name = new string(name);
}
void Speak() override {
cout << *m_Name << "小猫在说话!" << endl;
}
~Cat() {
cout << "Cat析构函数调用!" << endl;
if (this->m_Name != NULL) {
delete m_Name;
m_Name = NULL;
}
}
string *m_Name;
};
void test01() {
Animal *animal = new Cat("Tom");
animal->Speak();
delete animal;
}
int main() {
test01();
system("pause");
return 0;
}
6.5 多态案例:电脑组装
示例代码:
#include<iostream>
using namespace std;
//抽象CPU类
class CPU
{
public:
//抽象的计算函数
virtual void calculate() = 0;
};
//抽象显卡类
class VideoCard
{
public:
//抽象的显示函数
virtual void display() = 0;
};
//抽象内存条类
class Memory
{
public:
//抽象的存储函数
virtual void storage() = 0;
};
//电脑类
class Computer
{
public:
Computer(CPU* cpu, VideoCard* vc, Memory* mem)
{
m_cpu = cpu;
m_vc = vc;
m_mem = mem;
}
//提供工作的函数
void work()
{
//让零件工作起来,调用接口
m_cpu->calculate();
m_vc->display();
m_mem->storage();
}
//提供析构函数 释放3个电脑零件
~Computer()
{
//释放CPU零件
if (m_cpu != NULL)
{
delete m_cpu;
m_cpu = 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; //CPU的零件指针
VideoCard* m_vc; //显卡零件指针
Memory* m_mem; //内存条零件指针
};
//具体厂商
//Intel厂商
class IntelCPU :public CPU
{
public:
virtual void calculate()
{
cout << "Intel的CPU开始计算了!" << endl;
}
};
class IntelVideoCard :public VideoCard
{
public:
virtual void display()
{
cout << "Intel的显卡开始显示了!" << endl;
}
};
class IntelMemory :public Memory
{
public:
virtual void storage()
{
cout << "Intel的内存条开始存储了!" << endl;
}
};
//Lenovo厂商
class LenovoCPU :public CPU
{
public:
virtual void calculate()
{
cout << "Lenovo的CPU开始计算了!" << endl;
}
};
class LenovoVideoCard :public VideoCard
{
public:
virtual void display()
{
cout << "Lenovo的显卡开始显示了!" << endl;
}
};
class LenovoMemory :public Memory
{
public:
virtual void storage()
{
cout << "Lenovo的内存条开始存储了!" << endl;
}
};
void test01()
{
//第一台电脑零件
CPU* intelCpu = new IntelCPU;
VideoCard* intelCard = new IntelVideoCard;
Memory* intelMem = new IntelMemory;
cout << "第一台电脑开始工作:" << endl;
//创建第一台电脑
Computer* computer1 = new Computer(intelCpu, intelCard, intelMem);
computer1->work();
delete computer1;
cout << "-----------------------" << endl;
cout << "第二台电脑开始工作:" << endl;
//第二台电脑组装
Computer* computer2 = new Computer(new LenovoCPU, new LenovoVideoCard, new
LenovoMemory);;
computer2->work();
delete computer2;
cout << "-----------------------" << endl;
cout << "第三台电脑开始工作:" << endl;
//第三台电脑组装
Computer* computer3 = new Computer(new LenovoCPU, new IntelVideoCard, new
LenovoMemory);;
computer3->work();
delete computer3;
}
int main()
{
test01();
system("pause");
return 0;
}
7. 文件操作
文件操作允许程序将数据持久化到磁盘。
7.1 文本文件
打开方式 解释
ios::in 为读文件而打开文件
ios::out 为写文件而打开文件
ios::ate 初始位置:文件尾
ios::app 追加方式写文件
ios::trunc 如果文件存在先删除,再创建
ios::binary 二进制方式
C++中对文件操作需要包含头文件 < fstream >
文件类型分为两种:
- 文本文件 - 文件以文本的ASCII码形式存储在计算机中
- 二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类: - ofstream:写操作
- ifstream: 读操作
- fstream : 读写操作
5.1文本文件
5.1.1写文件
写文件步骤如下: - 包含头文件
#include <fstream> - 创建流对象
ofstream ofs; - 打开文件
ofs.open(“文件路径”,打开方式); - 写数据
ofs << “写入的数据”; - 关闭文件
ofs.close();
文件打开方式:
注意: 文件打开方式可以配合使用,利用|操作符
例如:用二进制方式写文件 ios::binary | ios:: out
7.1.1 写文件
示例代码:
#include <fstream>
void test01() {
ofstream ofs;
ofs.open("test.txt", ios::out);
ofs << "姓名:张三" << endl;
ofs << "性别:男" << endl;
ofs << "年龄:18" << endl;
ofs.close();
}
int main() {
test01();
system("pause");
return 0;
}
7.1.2 读文件
示例代码:
#include <fstream>
#include <string>
void test01()
{
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;
//}
//第二种
//char buf[1024] = { 0 };
//while (ifs.getline(buf,sizeof(buf)))
//{
// cout << buf << endl;
//}
//第三种
//string buf;
//while (getline(ifs, buf))
//{
// cout << buf << endl;
//}
char c;
while ((c = ifs.get()) != EOF)
{
cout << c;
}
ifs.close();
}
int main() {
test01();
system("pause");
return 0;
}
7.2.2 读文件
示例代码:
#include <fstream>
class Person {
public:
char m_Name[64];
int m_Age;
};
void test01() {
ifstream ifs("person.txt", ios::in | ios::binary);
if (!ifs.is_open()) {
cout << "文件打开失败" << endl;
return;
}
Person p;
ifs.read((char *)&p, sizeof(p));
cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
ifs.close();
}
int main() {
test01();
system("pause");
return 0;
}
总结
本专题详细介绍了C++面向对象编程的核心概念,包括内存分区模型、引用、函数、类和对象、继承、多态以及文件操作。通过丰富的代码示例和详细的讲解,帮助你深入理解C++面向对象编程的精髓。希望这篇文章能成为你学习C++的有力工具,帮助你在编程的道路上更进一步!