• C++之多态以及文件处理


    多态

    1 多态的基本概念

    多态是C++面向对象三大特性之一

    多态分为两类:

    静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名

    动态多态: 派生类和虚函数实现运行时多态

    静态多态和动态多态区别:

    静态多态的函数地址早绑定-编译阶段确定函数地址

    动态多态的函数地址晚绑定-运行阶段确定函数地址

    下面通过案例进行讲解多态

    1,静态多态的函数地址早绑定-编译阶段确定函数地址

    1. #include<iostream>
    2. using namespace std;
    3. //多态
    4. //动物类
    5. class Animal
    6. {
    7. public:
    8. void speak()
    9. {
    10. cout << "动物在说话" << endl;
    11. }
    12. };
    13. class Cat :public Animal
    14. {
    15. public:
    16. void speak()
    17. {
    18. cout << "小猫在说话" << endl;
    19. }
    20. };
    21. //执行说话的函数
    22. //静态多态的函数地址早绑定-编译阶段确定函数地址
    23. void doWork(Animal& animal)//Animal& animal = cat;
    24. {
    25. animal.speak();
    26. }
    27. void test()
    28. {
    29. Cat cat;
    30. doWork(cat);
    31. }
    32. int main()
    33. {
    34. test();
    35. system("pause");
    36. return 0;
    37. }

    如果想执行让小猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段绑定,地址晚绑定

    1. #include<iostream>
    2. using namespace std;
    3. //多态
    4. //动物类
    5. class Animal
    6. {
    7. public:
    8. //虚函数 加上virtual变成虚函数,那么编译器在编译的时候就不能缺点函数调用了
    9. //那么就只能在运行时确认函数地址,则变成晚绑定
    10. virtual void speak()
    11. {
    12. cout << "动物在说话" << endl;
    13. }
    14. };
    15. //猫类
    16. class Cat :public Animal
    17. {
    18. public:
    19. //重写 函数返回值类型 函数名 参数列表 完全相同
    20. virtual void speak()
    21. {
    22. cout << "小猫在说话" << endl;
    23. }
    24. };
    25. class Dog :public Animal
    26. {
    27. public:
    28. void speak()
    29. {
    30. cout << "小狗在说话" << endl;
    31. }
    32. };
    33. //我们希望传入什么对象,那么就调用什么对象的函数
    34. //如果函数地址在编译结点就能缺点,那么静态联编
    35. //如果函数地址在运行时才能缺点,那么就是动态联编
    36. void doWork(Animal& animal)//Animal& animal = cat;
    37. {
    38. animal.speak();
    39. }
    40. //执行说话的函数
    41. //静态多态的函数地址早绑定-编译阶段确定函数地址
    42. //如果想执行让小猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段绑定,地址晚绑定
    43. //动态多态满足条件:
    44. //1,有继承关系
    45. //2,子类出现父类的虚函数
    46. //动态多态使用
    47. //父类的指针或者引用 执行子类对象
    48. void test()
    49. {
    50. Cat cat;
    51. doWork(cat);
    52. Dog dog;
    53. doWork(dog);
    54. }
    55. int main()
    56. {
    57. test();
    58. system("pause");
    59. return 0;
    60. }

     

     总结:多态满足条件
    有继承关系
    子类重写父类中的虚函数
    多态使用条件:
    父类指针或引用指向子类对象
    重写:函数返回值类型 函数名 参数列表 完全一致称为重写

    2,多态案例——计算器类

    案例描述:

    分别利用普通写法和多态技术,设计实现两个操作数进行运算的计算器类

    多态的优点:

    代码组织结构清晰

    可读性强

    利于前期和后期的扩展以及维护

    示例:

    普通实现:

    1. #include<iostream>
    2. using namespace std;
    3. class Calculator
    4. {
    5. public:
    6. int getResult(string oper)
    7. {
    8. if (oper == "+")
    9. {
    10. return m_Num1 + m_Num2;
    11. }
    12. else if (oper == "-")
    13. {
    14. return m_Num1 - m_Num2;
    15. }
    16. else if (oper == "*")
    17. {
    18. return m_Num1 * m_Num2;
    19. }
    20. else
    21. {
    22. return m_Num1 / m_Num2;
    23. }
    24. }
    25. int m_Num1;//操作数1
    26. int m_Num2;//操作数2
    27. };
    28. void test()
    29. {
    30. Calculator c;
    31. c.m_Num1 = 100;
    32. c.m_Num2 = 100;
    33. cout << c.m_Num1 << "+" << c.m_Num2 << "=" << c.getResult("+") << endl;
    34. cout << c.m_Num1 << "-" << c.m_Num2 << "=" << c.getResult("-") << endl;
    35. cout << c.m_Num1 << "*" << c.m_Num2 << "=" << c.getResult("*") << endl;
    36. cout << c.m_Num1 << "/" << c.m_Num2 << "=" << c.getResult("/") << endl;
    37. }
    38. int main()
    39. {
    40. test();
    41. system("pause");
    42. return 0;
    43. }

     

    多态实现:

     如果想扩展新的功能,需要修改源码

    在真实开发中,提供 开闭原则

    开闭原则:对扩展进行开发,对修改进行关闭

    1. #include<iostream>
    2. using namespace std;
    3. #include<string>
    4. class AbstractCalculator
    5. {
    6. public:
    7. virtual int getResult()
    8. {
    9. return 0;
    10. }
    11. int m_Num1;//操作数1
    12. int m_Num2;//操作数2
    13. };
    14. class AddCalculator :public AbstractCalculator
    15. {
    16. int getResult()
    17. {
    18. return m_Num1 + m_Num2;
    19. }
    20. };
    21. class SubCalculator :public AbstractCalculator
    22. {
    23. int getResult()
    24. {
    25. return m_Num1 - m_Num2;
    26. }
    27. };
    28. class MulCalculator :public AbstractCalculator
    29. {
    30. int getResult()
    31. {
    32. return m_Num1 * m_Num2;
    33. }
    34. };
    35. class DivCalculator :public AbstractCalculator
    36. {
    37. int getResult()
    38. {
    39. return m_Num1 / m_Num2;
    40. }
    41. };
    42. void test()
    43. {
    44. //多态使用条件
    45. //父类制作或者引用指向子类对象
    46. AbstractCalculator* abs = new AddCalculator;
    47. abs->m_Num1 = 100;
    48. abs->m_Num2 = 100;
    49. cout << abs->m_Num1 << "+" << abs->m_Num2 << "=" << abs->getResult() << endl;
    50. //用完记得销毁
    51. delete abs;
    52. abs = new SubCalculator;
    53. abs->m_Num1 = 100;
    54. abs->m_Num2 = 100;
    55. cout << abs->m_Num1 << "-" << abs->m_Num2 << "=" << abs->getResult() << endl;
    56. //用完记得销毁
    57. delete abs;
    58. abs = new MulCalculator;
    59. abs->m_Num1 = 100;
    60. abs->m_Num2 = 100;
    61. cout << abs->m_Num1 << "*" << abs->m_Num2 << "=" << abs->getResult() << endl;
    62. //用完记得销毁
    63. delete abs;
    64. abs = new DivCalculator;
    65. abs->m_Num1 = 100;
    66. abs->m_Num2 = 100;
    67. cout << abs->m_Num1 << "/" << abs->m_Num2 << "=" << abs->getResult() << endl;
    68. //用完记得销毁
    69. delete abs;
    70. }
    71. int main()
    72. {
    73. test();
    74. system("pause");
    75. return 0;
    76. }

    利用多态实现计算器//多态好处:
    1、组织结构清晰
    2、可读性强
    3、对于前期和后期扩展以及维护性高 

    C++开发提出利用多态设计程序架构,因为多态优点很多 

    3,纯虚函数和抽象类

    在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容

    因此可以将虚函数改为纯虚函数

    纯虚函数语法:virtual 返回值类型 函数名(参数列表) = 0;

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

    抽象类特点:

    无法实例化对象

    子类必须重写抽象类中的纯虚函数,否则也属于抽象类

    1. #include<iostream>
    2. using namespace std;
    3. class Base
    4. {
    5. //纯虚函数
    6. //只要有一个纯虚函数,这个类就称为抽象类
    7. //抽象类特点:
    8. //1,无法实例化对象
    9. //2,抽象类的子类 必须要重写父类中的纯虚函数,否则也属于抽象类
    10. public:
    11. virtual void func() = 0;
    12. };
    13. class Son:public Base
    14. {
    15. public:
    16. virtual void func()
    17. {
    18. cout << "func 函数调用" << endl;
    19. };
    20. };
    21. void test()
    22. {
    23. //Base b;//抽象类无法实例化对象
    24. //new Base;//抽象类无法实例化对象
    25. Son s;//抽象类的子类 必须要重写父类中的纯虚函数,否则也属于抽象类
    26. Base * base = new Son;
    27. base->func();
    28. delete base;
    29. }
    30. int main()
    31. {
    32. test();
    33. system("pause");
    34. return 0;
    35. }

     

    4,多态案例二——制作饮品

    案例描述:

    制作饮品的大致流程为:煮水-冲泡-倒入杯中-加入辅料

    利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶

    1. #include<iostream>
    2. using namespace std;
    3. class AbstractDrinking
    4. {
    5. public:
    6. //煮水
    7. virtual void Boil() = 0;
    8. //冲泡
    9. virtual void Brew() = 0;
    10. //倒入杯中
    11. virtual void PourInCup() = 0;
    12. //加入辅料
    13. virtual void PutSomething() = 0;
    14. void makeDrink()
    15. {
    16. Boil();
    17. Brew();
    18. PourInCup();
    19. PutSomething();
    20. }
    21. };
    22. //制作咖啡
    23. class Coffee :public AbstractDrinking
    24. {
    25. public:
    26. //煮水
    27. virtual void Boil()
    28. {
    29. cout << "煮开水" << endl;
    30. }
    31. //冲泡
    32. virtual void Brew()
    33. {
    34. cout << "冲泡咖啡" << endl;
    35. }
    36. //倒入杯中
    37. virtual void PourInCup()
    38. {
    39. cout << "倒入杯中" << endl;
    40. }
    41. //加入辅料
    42. virtual void PutSomething()
    43. {
    44. cout << "加入牛奶和糖" << endl;
    45. }
    46. };
    47. //制作茶
    48. class Tea :public AbstractDrinking
    49. {
    50. public:
    51. //煮水
    52. virtual void Boil()
    53. {
    54. cout << "煮开水" << endl;
    55. }
    56. //冲泡
    57. virtual void Brew()
    58. {
    59. cout << "冲泡茶叶" << endl;
    60. }
    61. //倒入杯中
    62. virtual void PourInCup()
    63. {
    64. cout << "倒入杯中" << endl;
    65. }
    66. //加入辅料
    67. virtual void PutSomething()
    68. {
    69. cout << "加入枸杞" << endl;
    70. }
    71. };
    72. //制作函数
    73. void doWork(AbstractDrinking* abs)
    74. {
    75. abs->makeDrink();
    76. delete abs;
    77. }
    78. void test()
    79. {
    80. //制作咖啡
    81. cout << "制作咖啡:" << endl;
    82. doWork(new Coffee);
    83. cout << "---------------------" << endl;
    84. cout << "制作茶:" << endl;
    85. //制作茶
    86. doWork(new Tea);
    87. }
    88. int main()
    89. {
    90. test();
    91. system("pause");
    92. return 0;
    93. }

     

     

    5,虚构函数和纯虚函数

    多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码

    解决方式:将父类中的析构函数改为虚析构或者纯虚析构

    虚析构和纯虚析构共性:

    可以解决父类指针释放子类对象

    都需要有具体的函数实现

    虚析构和纯虚析构区别:

    如果是纯虚析构,该类属于抽象类,无法实例化对象

    虚析构函数的语法:

    virtual ~类名(){}

    纯虚析构语法:

    virtual ~类名()=0;

    1. #include<iostream>
    2. using namespace std;
    3. #include<string>
    4. //动物类
    5. class Animal
    6. {
    7. public:
    8. Animal()
    9. {
    10. cout << "Animal构造函数调用" << endl;
    11. }
    12. //利用虚析构函数可以解决 父类指针释放子类对象时不干净的问题
    13. //~Animal()
    14. //{
    15. // cout << "Animal析构函数调用" << endl;
    16. //}
    17. //纯虚析构 需要声明也需要实现
    18. //有了纯虚析构之后,这个类也属于抽象类,无法实例化对象
    19. virtual ~Animal() = 0;
    20. //纯虚函数
    21. virtual void speak() = 0;
    22. };
    23. Animal:: ~Animal()
    24. {
    25. }
    26. //猫类
    27. class Cat :public Animal
    28. {
    29. public:
    30. Cat(string name)
    31. {
    32. cout << "Cat构造函数调用" << endl;
    33. m_Name = new string(name);
    34. }
    35. //重写 函数返回值类型 函数名 参数列表 完全相同
    36. virtual void speak()
    37. {
    38. cout << "小猫在说话" << endl;
    39. }
    40. ~Cat()
    41. {
    42. if (m_Name != NULL)
    43. {
    44. cout << "Cat析构函数调用" << endl;
    45. delete m_Name;
    46. m_Name = NULL;
    47. }
    48. }
    49. string *m_Name;
    50. };
    51. void doWork(Animal& animal)//Animal& animal = cat;
    52. {
    53. animal.speak();
    54. }
    55. void test()
    56. {
    57. Animal* animal = new Cat("Tom");
    58. animal->speak();
    59. //父类指针在析构时候,不会调用子类中析构函数,
    60. // 导致子类如果有堆区属性,出现内存泄露情况
    61. delete animal;
    62. }
    63. int main()
    64. {
    65. test();
    66. system("pause");
    67. return 0;
    68. }

     

    总结: 

    1.虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
    2.如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
    3.拥有纯虚析构函数的类也属于抽象类 

    6,多态案例三——电脑组装

    案例描述:

    电脑主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储)将每个零件封装出抽象基

    类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商创建电脑类提供让电脑工

    作的函数,并且调用每个零件工作的接口测试时组装三台不同的电脑进行工作

    1. #include<iostream>
    2. using namespace std;
    3. #include<string>
    4. class CPU//抽象出每个零件的类
    5. {
    6. public:
    7. //抽象计算函数
    8. virtual void calculate() = 0;
    9. };
    10. //抽象的显卡
    11. class VideoCard
    12. {
    13. public:
    14. //抽象显示函数
    15. virtual void display () = 0;
    16. };
    17. //抽象类
    18. class Memory
    19. {
    20. public:
    21. //抽象存储函数
    22. virtual void storage() = 0;
    23. };
    24. //电脑类
    25. class Computer
    26. {
    27. public:
    28. Computer(CPU * cpu, VideoCard * vc, Memory * mem)
    29. {
    30. m_cpu = cpu;
    31. m_vc = vc;
    32. m_mem = mem;
    33. }
    34. //提供工作函数
    35. void work()
    36. {
    37. //让零件工作起来,调用接口
    38. m_cpu->calculate();
    39. m_vc->display();
    40. m_mem->storage();
    41. }
    42. //提供析构函数 释放3个电脑零件
    43. ~Computer()
    44. {
    45. //释放cpu零件
    46. if (m_cpu != NULL)
    47. {
    48. delete m_cpu;
    49. m_cpu = NULL;
    50. }
    51. //释放显卡零件
    52. if (m_vc != NULL)
    53. {
    54. delete m_vc;
    55. m_vc = NULL;
    56. }
    57. //释放mem零件
    58. if (m_mem != NULL)
    59. {
    60. delete m_mem;
    61. m_mem = NULL;
    62. }
    63. }
    64. private:
    65. //构造函数中传入三个零件指针
    66. CPU * m_cpu;//CPU零件指针
    67. VideoCard * m_vc;//显卡零件指针
    68. Memory * m_mem;//内存条零件指针
    69. };
    70. //具体厂商
    71. //Inter厂商
    72. class InterCPU :public CPU
    73. {
    74. public:
    75. virtual void calculate()
    76. {
    77. cout << "Inter的COU开始计算!" << endl;
    78. }
    79. };
    80. class InterCard :public VideoCard
    81. {
    82. public:
    83. virtual void display()
    84. {
    85. cout << "Inter的显卡开始显示!" << endl;
    86. }
    87. };
    88. class InterMemory :public Memory
    89. {
    90. public:
    91. virtual void storage()
    92. {
    93. cout << "Inter的内存条开始存储!" << endl;
    94. }
    95. };
    96. //Lenovo厂商
    97. class LenovoCPU :public CPU
    98. {
    99. public:
    100. virtual void calculate()
    101. {
    102. cout << "Lenovo的COU开始计算!" << endl;
    103. }
    104. };
    105. class LenovoCard :public VideoCard
    106. {
    107. public:
    108. virtual void display()
    109. {
    110. cout << "Lenovo的显卡开始显示!" << endl;
    111. }
    112. };
    113. class LenovoMemory :public Memory
    114. {
    115. public:
    116. virtual void storage()
    117. {
    118. cout << "Lenovo的内存条开始存储!" << endl;
    119. }
    120. };
    121. void test01()
    122. {
    123. //第一台电脑的零件
    124. CPU* interCpu = new InterCPU;
    125. VideoCard* interCard = new InterCard;
    126. Memory* interMem = new InterMemory;
    127. //创建第一台电脑
    128. cout << "第一台电脑开始工作" << endl;
    129. Computer* computer1 = new Computer(interCpu, interCard, interMem);
    130. computer1->work();
    131. delete computer1;
    132. //第二台电脑组装
    133. cout << "------------------------" << endl;
    134. cout << "第二台电脑开始工作" << endl;
    135. Computer* computer2 = new Computer(new LenovoCPU, new LenovoCard, new LenovoMemory);
    136. computer2->work();
    137. delete computer2;
    138. //第三台电脑组装
    139. cout << "------------------------" << endl;
    140. cout << "第三台电脑开始工作" << endl;
    141. Computer* computer3 = new Computer(new LenovoCPU, new InterCard, new LenovoMemory);
    142. computer3->work();
    143. delete computer3;
    144. }
    145. int main()
    146. {
    147. test01();
    148. system("pause");
    149. return 0;
    150. }

    文件操作

    程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放

    通过文件可以将数据持久化

    C++中对文件操作需要包含头文件
    文件类型分为两种:
    1.文本文件 文件以文本的ASCII码形式存储在计算机中
    2.二进制文件- 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们

    操作文件的三大类:
    1.ofstream:写操作
    2.ifstream: 读操作
    3.fstream : 读写操作

    1,写文本

    写文件步骤如下
    1.包含头文件
    #indude
    2. 创建流对象
    ofstream ofs;
    3. 打开文件
    ofs.open("文件路径",打开方式);
    4. 写数据
    ofs<<"写入的数据”;
    5.关闭文件
    ofs.close();

    文件打开方式:

    1. 打开方式                 解释
      ios::in为读文件而打开文件
      ios::out为写文件为打开文件
      ios::ate初始位置:文件尾
      ios::app追加方式写文件
      ios::trunc如果文件存在先删除,再船舰
      ios::binary二进制方式

     注意: 文件打开方式可以配合使用,利用 | 操作符
    例如:用二进制方式写文件ios::binary | ios::out

    代码展示:

    1. #include<iostream>
    2. using namespace std;
    3. #include<fstream>//头文件包含
    4. void test()
    5. {
    6. //1.包含头文件
    7. //#indude < fstream>
    8. //2. 创建流对象
    9. ofstream ofs;
    10. //3. 指定打开方式
    11. ofs.open("text.txt", ios::out);
    12. //4. 写数据
    13. ofs << "姓名:张三"<<endl;
    14. ofs << "年龄:18" << endl;
    15. ofs << "性别:男" << endl;
    16. //
    17. //5.关闭文件
    18. ofs.close();
    19. }
    20. int main()
    21. {
    22. test();
    23. system("pause");
    24. return 0;
    25. }

    虽然再运行中未显示 ,但是打开text文件可以看到输入的内容

     

     

     

     

    总结:
    文件操作必须包含头文件 fstream
    读文件可以利用 ofstream,或者fstream类
    打开文件时候需要指定操作文件的路径,以及打开方式
    利用<<可以向文件中写数据
    操作完毕,要关闭文件 

    2,读文件

    读文件与写文件步骤相似,但是读取方式相对于比较多

    读文件步骤如下:
    1.包含头文件
    #include
    2.创建流对象
    ifstream ifs;
    3.打开文件并判断文件是否打开成功
    ifs.open("文件路径",打开方式);
    4. 读数据
    四种方式读取
    5.关闭文件
    ifs.close();

    示例:

    1. #include<iostream>
    2. using namespace std;
    3. #include<fstream>//头文件包含
    4. #include<string>
    5. void test()
    6. {
    7. //1.包含头文件
    8. //#indude < fstream>
    9. //2. 创建流对象
    10. ofstream ofs;//写文件
    11. ifstream ifs;//读文件
    12. //3. 指定打开方式
    13. ofs.open("text1.txt", ios::out);
    14. //4. 写数据
    15. ofs << "姓名:张三" << endl;
    16. ofs << "年龄:18" << endl;
    17. ofs << "性别:男" << endl;
    18. ifs.open("text1.txt", ios::in);
    19. if (!ifs.is_open())
    20. {
    21. cout << "文件打开失败" << endl;
    22. return;
    23. }
    24. // 读数据
    25. //第一种
    26. //char buf[1024] = { 0 };
    27. //while (ifs >> buf)
    28. //{
    29. // cout << buf << endl;
    30. //}
    31. //第二种
    32. char buf[1024] = { 0 };
    33. while (ifs.getline(buf,sizeof(buf)))
    34. {
    35. cout << buf << endl;
    36. }
    37. //第三种
    38. //string buf;
    39. //while ( getline(ifs, buf) )
    40. //{
    41. // cout << buf << endl;
    42. //}
    43. //第四种
    44. //char c;
    45. //while ((c = ifs.get()) != EOF)//EOF==end of file
    46. //{
    47. // cout << c;
    48. //}
    49. //5.关闭文件
    50. ifs.close();
    51. }
    52. int main()
    53. {
    54. test();
    55. system("pause");
    56. return 0;
    57. }

    3, 二进制文件

    3.1写文件

    以二进制的方式对文件进行读写操作
    打开方式要指定为 ios::binany

    二进制方式写文件主要利用流对象调用成员函数write
    函数原型:ostream& write(const char*buffer,int len);
    参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数

    1. #include<iostream>
    2. using namespace std;
    3. #include<fstream>//头文件包含
    4. class Person
    5. {
    6. public:
    7. char m_Name[64];
    8. int m_Age;
    9. };
    10. void test()
    11. {
    12. //1.包含头文件
    13. //#indude < fstream>
    14. //2. 创建流对象
    15. ofstream ofs("person.txt", ios::out | ios::binary);
    16. //3. 指定打开方式
    17. //ofs.open("person.txt", ios::out|ios::binary);
    18. //4. 写数据
    19. Person p = { "张三",18 };
    20. ofs.write((const char*)&p, sizeof(p));
    21. //5.关闭文件
    22. ofs.close();
    23. }
    24. int main()
    25. {
    26. test();
    27. system("pause");
    28. return 0;
    29. }

    总结:
    文件输出流对象 可以通过write函数,以二进制方式写数据

    3.2 读文件

    二进制方式读文件主要利用流对象调用成员函数read
    函数原型:istream&read(char *buffer,int len);
    参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
    示例:

    1. #include<iostream>
    2. using namespace std;
    3. #include<fstream>//头文件包含
    4. class Person
    5. {
    6. public:
    7. char m_Name[64];
    8. int m_Age;
    9. };
    10. void test01()
    11. {
    12. //1.包含头文件
    13. //#indude < fstream>
    14. //2. 创建流对象
    15. ofstream ofs("person.txt", ios::out | ios::binary);
    16. //3. 指定打开方式
    17. //ofs.open("person.txt", ios::out|ios::binary);
    18. //4. 写数据
    19. Person p = { "张三",18 };
    20. ofs.write((const char*)&p, sizeof(p));
    21. //5.关闭文件
    22. ofs.close();
    23. }
    24. void test02()
    25. {
    26. //1.包含头文件
    27. //#indude < fstream>
    28. //2. 创建流对象
    29. ifstream ifs;
    30. //3. 指定打开方式
    31. ifs.open("person.txt", ios::out|ios::binary);
    32. if (!ifs.is_open())
    33. {
    34. cout << "文件打开失败" << endl;
    35. return;
    36. }
    37. //4. 读数据
    38. Person p;
    39. ifs.read((char*)&p, sizeof(p));
    40. cout << "姓名:" << p.m_Name << "年龄:" << p.m_Age << endl;
    41. //5.关闭文件
    42. ifs.close();
    43. }
    44. int main()
    45. {
    46. test01();
    47. test02();
    48. system("pause");
    49. return 0;
    50. }

  • 相关阅读:
    【java】基础知识(1)
    图解设计模式:身份认证场景的应用
    C++11各种锁的具体使用
    使用kubeseal加密和管理k8s集群的secret
    MySql分区简单说明
    KNN最近邻算法分析及实现(Python实现)
    【操作系统】系统启动流程
    【UE4 反射系统】 UCLAS UFUNCTION UPROPERTY 宏简单解析 持续更新
    spark中结合源码理解reduceByKey、groupByKey、combineByKey等几个ByKey算子的区别
    Win10操作系统安装Python
  • 原文地址:https://blog.csdn.net/bai_lan_ya/article/details/136649093