Advertisement

【C++】基础语法总结复习

阅读量:

文章目录

  • 一、C++语言的历史

  • 二、C++语言基础**

    • 1、"Hello World"

    • 2、数据类型

    • 3、转义字符

    • 4、变量与常量

    • 4.1、标识符与关键字

      • 4.1.1 标识符
      • 4.1.2 关键字
    • 4.2、变量

    • 4.3、常量

    • 5、运算符

    • 6、控制结构

      • 6.1、顺序结构
      • 6.2、选择结构
      • 6.3、循环结构
    • 7、函数

    • 8、构造数据类型

      • 8.1、枚举
      • 8.2、数组
      • 8.3、指针
      • 8.4、引用
      • 8.3、结构与联合
    • 9、类与对象

      • 9.1、类与对象的概念
        • 9.1.1、类
    • 9.1.2、对象

      • 9.2、构造函数与析构函数
        • 9.2.1、构造函数(Constructor)
    • 9.2.2、析构函数(Destructor)

    • 10、封装、继承和多态

      • 10.1、封装
      • 10.2、继承
      • 10.3、多态
    • 11、模板

      • 11.1、函数模板
      • 11.2、类模板
    • 12、输入/输出流与文件系统

      • 12.1、输入\输出流
      • 12.2、文件管理
        • 12.2.1、 文件读取操作 (ifstream)
    • 12.2.2、 文件写入操作 (ofstream)

    • 12.2.3、 同时读写文件 (fstream)

    • 13、异常处理

  • 三、总结**

  • 参考文献

前言随笔 :很多东西经常不用,慢慢的就忘记了,刚好对之前的c++笔记做个整理,就当作复习了。

一、C++语言的历史

C++ 是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由Bjarne Stroustrup (见下图)在AT&T贝尔工作室研发。
C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计。C++几乎可以创建任何类型的程序:游戏、设备驱动程序、HPC、云、桌面、嵌入式和移动应用等。 甚至用于其他编程语言的库和编译器也使用C++编写。
Bjarne Stroustrup

时间轴 发展

1979年

贝尔实验室的 Bjarne Stroustmp 开始对C语言进行改进,为其加入面向对象的特性。最初,这种新语言被称为“带类的C(C with Classes)” 。
1985年 1985 年,C++ 最权威的著作、由 Bjarne Stroustmp 撰写的《C++程序设计语言》(The C++ Programming Language)第一版发布。
1989年 1989 年,C++ 2.0 版发布,加入了多重继承、抽象类、静态成员、常量成员函数等概念。
1990年 加入了模板、异常处理、名字空间等机制。
1994年 ANSI C++ 标准发布。
1998年 NSI(美国国家标准协会)和 ISO(国际标准化组织)联合发布了至今使用最为广泛的 C++ 标准,称为 C++ 98。C++ 98 最为重大的改进就是加入了 “标准模板库”(Standard Template Library, STL),使得“泛型程序设计”成为 C++ 除“面向对象”外的另一主要特点。
2003年 ISO 的 C++ 标准委员会又对 C++ 略做了一些修订,发布了 C++ 03 标准。C++ 03 和 C++ 98 的区别对大多数程序员来说可以不必关心。
2005年 一份名为 Library Technical Report 1(简称 TR1)的技术报告发布,为 C++ 加入了正则表达式、哈希表等重要类模板。虽然 TR1 当时没有正式成为 C++ 标准,但如今的许多 C++ 编译器都已经支持 TR1 中的特性。
2011年 ISO 通过了新的 C+ + 标准,这就是 C++11。C++11 在酝酿的过程中被称为 C++ 0x,因为 Bjame Stroustmp 原本预计它应该在 2008 年或 2009 年发布。 C++11是 C++ 语言的一个重要版本,它大幅度改进了 C++,引入了许多新的特性和库,提升了语言的现代性,增强了开发效率
2014年 C++14作为C++11的修正版,主要对C++11中的一些特性进行了修正和小范围的增强。
2017年 C++17引入了许多新的功能和库,改进了 C++ 语言的现代性和效率。
2020年 C++20是 C++ 语言的一个重要版本,加入了许多现代化的特性,进一步提升了语言的表达能力和性能。
2023年 C++23标准于2023年末正式通过,并已进入广泛采用阶段。C++23在C++20的基础上,进一步增强了语言功能和标准库的便利性。
2024年 C++24仍处于制定标准和提案讨论阶段。

二、C++语言基础**

1、“Hello World”

每个初学者都是从"Hello World"打开了新世界的大门,上来给你一串代码,但很多时候不知道为什么,先进行“模仿”,在进行练习,很多东西都是在使用过程中学会了,才有了自己的思考。哈哈,扯远了,见下图。
在这里插入图片描述

  • include:包含;把……列为一部分,把……算入;
  • stdio:标准输入输出;
  • void:空的;
  • main:主要的;
  • printf:写格式化输出;打印函数;
  • return:回应;

2、数据类型

C++的基本数据类型大体上可分为布尔型、字符型、整数型、浮点型、双浮点型、空值型和宽字符型。

复制代码
    注意:当一个变量被赋予一个超过其最大值的数值时,它会发生溢出。
    
    
      
    

在这里插入图片描述
在这里插入图片描述

3、转义字符

对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。
在这里插入图片描述

4、变量与常量

4.1、标识符与关键字

4.1.1 标识符

  1. 标识符由字母、数字、下划线“_”组成。
  2. 不能把C++关键字作为标识符。
  3. 标识符长度限制32字符。
  4. 标识符对大小写敏感。
  5. 首字符只能是字母或下划线,不能是数字。

4.1.2 关键字

关键字是编程语言中的预定义的保留字,具有特殊的语法意义。它们是语言的一部分,用于实现语言的控制结构、数据类型定义、函数行为等。程序员不能将这些关键字用作标识符(如变量名、函数名等)。关键字在程序执行过程中被编译器识别并处理,是构成程序语法和语义的基础。
在这里插入图片描述

4.2、变量

在 C++ 中,变量的定义是指声明一个变量并为其指定类型,之后你可以给该变量赋值以存储数据。变量的定义包括以下几个基本要素:
1. 数据类型:指定变量能够存储的数据类型(如 int、double、char 等)。
2. 变量名:变量的标识符,用于在程序中引用该变量。
3. 可选的初始值:在定义时,变量可以被赋一个初始值。
在这里插入图片描述

4.3、常量

在 C++ 中,常量(const)是指在程序执行过程中,其值不可改变的变量。常量用于保护一些不应修改的数据,能够提高程序的可靠性和可读性。
如果一个变量被const修饰,那么它的值就不能再被改变。

  1. 指针常量 :const修饰一个常量,且它为指针,被const修饰的值不能被修改,即这个指针不能被改变,而指针指向的地址可以被修改。
  2. 常量指针 :指向常量的指针,指针本身可以改变,可以指向不同的内容,但是它所指向的内容是不可修改的。
复制代码
    #include <stdio.h>
    int main() 
    {
    	int x = 123;
    	int	y = 456;
    
    	// 指针常量
    	int* const ptr_x = &x;
    	*ptr_x = 30;  // 合法,可以修改指针指向的值
    	//ptr_x = &y;  // 非法,不能修改指针本身的值(指向的地址)
    
    	// 常量指针
    	const int* ptr_y = &x;
    	ptr_y = &y;  // 合法,可以修改指针指向的地址
    	// *ptr_y = 40;  // 非法,不能通过指针修改指向的值
    
    	printf("x = %d, y = %d\n", x, y);
    	printf("*ptr_x = %d, *ptr_y = %d\n", *ptr_x, *ptr_y);
    
    	return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

5、运算符

在 C++ 中,运算符是用于执行操作的符号或关键字,它们可以对数据进行计算、比较、赋值或修改等操作。
在这里插入图片描述

6、控制结构

在程序设计语言中控制结构用于指明程序的执行流程。C++包括提供的基本控制结构分为三种:
1. 顺序结构:按照先后顺序依次执行程序中的语句。
2. 选择结构:按照给定条件有选择地执行程序中的语句。
3. 循环结构:按照给定规则重复地执行程序中的语句。

6.1、顺序结构

顺序结构是最简单的控制结构,指的是程序从上到下、按顺序逐行执行语句。

6.2、选择结构

1. if 语句:根据条件是否为真,执行相应的代码。
2. if-else 语句:如果条件为真执行一部分代码,条件为假执行另一部分代码。
3. else-if 语句:多个条件依次判断,选择执行第一个满足条件的代码块。
4. switch 语句:根据不同的值来选择执行不同的代码块,通常用于多重条件判断。

复制代码
    #include <iostream>
    using namespace std;
    int main()
    {
    int a = 5, b = 3;
    if (a > b) {
        cout << "a is greater than b" << endl;
    } else {
        cout << "a is less than or equal to b" << endl;
    }
    
    enum color { RED, GREEN, BLUE };
    switch (RED)
    {
        case RED:
            std::cout << "red\n";
            break;
        case GREEN:
            std::cout << "green\n";
            break;
        case BLUE:
            std::cout << "blue\n";
            break;
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

6.3、循环结构

循环结构允许程序在满足特定条件时重复执行某些代码。常见的循环结构包括 for 循环、while 循环和 do-while 循环。

复制代码
    #include <iostream>
    using namespace std;
    
    int main()
     {
    // for 循环示例
    for (int i = 0; i < 5; i++) 
    {
        cout << i << " ";
    }
    cout << endl;
    
    // while 循环示例
    int j = 0;
    while (j < 5)
    {
        cout << j << " ";
        j++;
    }
    cout << endl;
    
    // do-while 循环示例
    int k = 0;
    do
    {
        cout << k << " ";
        k++;
    } while (k < 5);
    cout << endl;
    
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

7、函数

函数(function)是把一个语句序列(函数体, function body)关联到一个名字和零或更多个函数形参(function parameter)的列表的 C++ 实体。每个函数都是一个独立的模块,绝不允许在一个函数体内定义另外一个函数。
通俗的讲,就是把一段经常使用的代码封装起来,减少重复代码。

复制代码
    #include <iostream>
    
    // 用户自定义函数 doPrint()
    void doPrint() // doPrint() 是被调函数
    {
    std::cout << "In doPrint()\n";
    }
    
    // 定义函数 main()
    int main()
    {
    std::cout << "Starting main()\n";
    doPrint(); // 去执行函数 doPrint().  main() 是调用者.
    std::cout << "Ending main()\n"; // doPrint() 执行结束后,返回这里继续执行
    
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

8、构造数据类型

8.1、枚举

如果一个变量只有集中可能的取值,可以使用枚举类型进行定义。枚举类型属于用户自定义的数据类型。枚举声明的一般类型如下。

复制代码
    enum country_name
    {
    CHINA 1,
    USA   2,
    Korea
    }
    
    
      
      
      
      
      
      
    

注意:

  • 枚举类型名以及枚举常量为标识符,遵循标识符的取名规则。
  • 在定义一个枚举类型时定义了多个常量,供枚举类型变量取值,我们称此常量为枚举常量。当没有给枚举常量指定值时,其值默认为0、1、2、…在定义枚举类型时,也可以使用赋值号另外指定枚举常量的值。

8.2、数组

在C++中,数组是一种数据结构,用于存储固定大小的相同类型元素的顺序集合。数组的每个元素可以通过索引访问,索引从0开始。数组在内存中占用连续的空间,最低地址对应第一个元素,最高地址对应最后一个元素。

复制代码
    #include <iostream>
    using namespace std;
     
    #include <iomanip>
    using std::setw;
     
    int main ()
    {
       int n[ 10 ]; // n 是一个包含 10 个整数的数组
     
       // 初始化数组元素          
       for ( int i = 0; i < 10; i++ )
       {
      n[ i ] = i + 100; // 设置元素 i 为 i + 100
       }
       cout << "Element" << setw( 13 ) << "Value" << endl;
     
       // 输出数组中每个元素的值                     
       for ( int j = 0; j < 10; j++ )
       {
      cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;
       }
     
       return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

8.3、指针

指针是一种特殊的变量,它存储的是另一个变量的内存地址,而不是实际的数据值。通过指针,你可以间接地访问和操作存储在该内存地址中的数据。
在C++中,有几种特殊的指针类型,它们用于特定的用途。以下是常见的几种特殊指针类型及其解释:

  • 空指针 (Null Pointer):

空指针是指向“无效”内存地址的指针。通常用于表示指针未初始化或不指向任何有效的对象。
nullptr 是 C++11 引入的关键字,表示一个空指针。

复制代码
       int* ptr = nullptr;
    
    
      
    
  • 野指针 (Dangling Pointer):

野指针是指向已经被释放或超出作用域的内存的指针。使用野指针会导致未定义行为。

复制代码
       int* ptr = new int(10);  // 动态分配内存
       delete ptr;              // 释放内存
       // ptr 现在是一个野指针
    
    
      
      
      
    
  • 常量指针 (Constant Pointer):

常量指针是指针本身的值不能被改变,但它指向的内容是可以修改的。

复制代码
       int x = 10;
       int* const ptr = &x;  // ptr 是常量指针
       *ptr = 20;            // 可以修改 ptr 指向的值
       // ptr = &y;          // 错误:不能改变指针 ptr 的指向
    
    
      
      
      
      
    
  • 指针常量 (Pointer to Constant):

指针常量是指针可以改变,但它指向的数据内容是常量,不能修改。

复制代码
      const int* ptr = &x;  // ptr 是指向常量的指针
      *ptr = 20;            // 错误:不能修改 *ptr 的值
       ptr = &y;             // 可以改变 ptr 指向的地址
    
    
      
      
      
    
  • 常量指针常量 (Constant Pointer to Constant):

常量指针常量是指既不能改变指针本身的值,也不能修改指针所指向的数据。

复制代码
      const int* const ptr = &x;  // ptr 是常量指针常量
      *ptr = 20;                  // 错误:不能修改 *ptr 的值
       ptr = &y;                   // 错误:不能改变 ptr 的指向
    
    
      
      
      
    
  • 函数指针 (Function Pointer):

函数指针是指向函数的指针,可以用来调用函数。

复制代码
      void (*funcPtr)(int);  // 声明一个函数指针,指向接受一个 int 类型参数并返回 void 的函数
      void myFunction(int x)
       {
      std::cout << x << std::endl;
      }
      funcPtr = myFunction;  // 将函数指针指向 myFunction
      funcPtr(10);           // 调用 myFunction,通过函数指针
    
    
      
      
      
      
      
      
      
    
  • 指针数组 (Array of Pointers):

指针数组是一个数组,其中的每个元素都是指针。常用于存储多个指针。

复制代码
      int* arr[10];  // 一个包含 10 个整数指针的数组
    
    
      
    

指针指针 (Pointer to Pointer):

指针指针是指向指针的指针,用来间接访问指针所指向的内存。

复制代码
      int x = 10;
      int* ptr = &x;
      int** ptr2 = &ptr;  // ptr2 是指向 ptr 的指针
    
    
      
      
      
    
  • 智能指针 (Smart Pointer):

智能指针是 C++11 引入的类,用来自动管理动态分配的内存,避免内存泄漏。
std::unique_ptr:表示唯一所有权,不能共享。
std::shared_ptr:表示共享所有权,多个指针可以共享同一个对象。
std::weak_ptr:用于解决 shared_ptr 的循环引用问题。

复制代码
      std::unique_ptr<int> ptr = std::make_unique<int>(10);
      std::shared_ptr<int> sptr = std::make_shared<int>(20);
    
    
      
      
    

8.4、引用

从逻辑上理解﹐引用(reference)是已存在变量的别名(alias)。通过引用﹐我们可以间接访问变量,指针也能间接访问变量,但引用在使用上比指针更安全。引用的主要用途是描述函数的参数和返回值,特别是传递较大的数据变量。
在这里插入图片描述

8.3、结构与联合

数组是由类型相同的数据元素构成的,然而,在程序中往往需要处理一些由不同类型数据元素所构成的数据。例如,一个学生的基本情况由学号、姓名、性别、出生日期、成绩等数据元素构成,这些数据元素具有不同的数据类型,如果使用独立的不同数据类型的变量来描述这些信息,那么变量之间的关系不能体现出来。C++提供了描述不同数据类型的组合体的方法,即结构(struct)与联合(uion)。

9、类与对象

9.1、类与对象的概念

类和对象是面向对象编程(OOP)中的两个核心概念。在C++以及其他OOP语言中,它们提供了一种结构化和组织化代码的方式,使得程序更加模块化、可维护和可扩展。

9.1.1、类

类是一种自定义的数据类型,它是描述一组具有相同属性和行为的对象的模板。类定义了对象的属性(数据成员)和方法(成员函数),并且可以封装相关的功能。

9.1.2、对象

对象是类的一个实例,是根据类的模板创建的实体。类定义了对象的属性和行为,而对象则是类的实际应用,每个对象可以拥有不同的属性值。

复制代码
    int main() {
    // 创建对象
    Car car1;  // car1 是 Car 类的一个对象
    Car car2;  // car2 是另一个 Car 类的对象
    
    // 给对象 car1 的成员赋值
    car1.brand = "Toyota";
    car1.year = 2020;
    
    // 给对象 car2 的成员赋值
    car2.brand = "Honda";
    car2.year = 2018;
    
    // 调用对象的成员函数
    car1.displayInfo();
    car2.displayInfo();
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

9.2、构造函数与析构函数

构造函数和析构函数是面向对象编程(OOP)中用于初始化和清理对象的特殊成员函数。它们通常在类中定义,用于对象的生命周期管理。

9.2.1、构造函数(Constructor)

构造函数是当一个对象被创建时自动调用的特殊函数。它主要用于初始化对象的状态或进行资源的分配。

特点:

  • 自动调用:当创建对象时,构造函数会被自动调用。
  • 名称与类相同:构造函数的名称必须与类的名称相同。
  • 没有返回值:构造函数没有返回值类型,甚至不可以指定 void。
  • 可以有多个重载:一个类可以有多个构造函数,分别接收不同的参数(构造函数重载)。
9.2.2、析构函数(Destructor)

析构函数是当对象生命周期结束时自动调用的特殊函数。它主要用于释放构造函数中分配的资源,防止内存泄漏和其他资源浪费。

特点:

  • 自动调用:当对象生命周期结束时,析构函数会被自动调用。
  • 名称与类相同,但前面加上~ :析构函数的名称必须与类名相同,但在函数名前加一个波浪号(~)。
  • 没有返回值:析构函数没有返回值类型,也不能指定 void。
  • 不能有参数:析构函数不能有参数,因此不能进行重载。

10、封装、继承和多态

封装、继承和多态是面向对象编程(OOP)的三大基本特性。

  • 封装:将客观事物封装成抽象的类,⽽而类可以把⾃自⼰己的数据和⽅方法暴暴露露给可信的类或者对象,对不不可信的类或
    对象则进⾏行行信息隐藏。

  • 继承:可以使⽤用现有类的所有功能,并且⽆无需重新编写原来的类即可对功能进⾏行行拓拓展;

  • 多态:⼀一个类实例例的相同⽅方法在不不同情形下有不不同的表现形式,使不不同内部结构的对象可以共享相同的外部接口。

10.1、封装

在C++中,封装通过类来实现。类内部的成员变量通常设为私有(private),并通过公共(public)方法来访问和修改它们。

复制代码
    #include <iostream>
    using namespace std;
    
    class Circle {
    private:
    double radius;  // 私有成员变量
    
    public:
    // 公共成员函数,提供对radius的访问接口
    void setRadius(double r) {
        if (r > 0) {
            radius = r;
        }
    }
    
    double getRadius() const {
        return radius;
    }
    
    double getArea() const {
        return 3.14159 * radius * radius;
    }
    };
    
    int main() {
    Circle c;
    c.setRadius(5);  // 使用公共接口设置radius
    cout << "Radius: " << c.getRadius() << endl;
    cout << "Area: " << c.getArea() << endl;
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

10.2、继承

继承是面向对象编程的另一大特性,它允许一个类从另一个类继承属性和行为。通过继承,可以实现代码复用和扩展,减少重复代码。

  • 代码重用:子类可以继承父类的成员变量和成员函数,避免重复编写相同的代码。
  • 扩展功能:子类可以添加自己特有的成员,也可以重写父类的成员函数。
复制代码
    #include <iostream>
    using namespace std;
    
    class Animal {
    public:
    void eat() {
        cout << "Eating..." << endl;
    }
    };
    
    class Dog : public Animal {  // Dog 类继承自 Animal 类
    public:
    void bark() {
        cout << "Barking..." << endl;
    }
    };
    
    int main() {
    Dog dog;
    dog.eat();  // Dog 类继承了 Animal 类的 eat() 方法
    dog.bark(); // Dog 类自定义了 bark() 方法
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

10.3、多态

多态是指不同对象对相同消息(方法调用)做出不同响应的能力。多态通常通过“方法重载”和“方法重写”来实现。C++支持两种类型的多态:

  • 静态多态(编译时多态):通过方法重载(函数名相同,参数不同)和运算符重载实现。
  • 动态多态(运行时多态):通过继承和虚函数(virtual)机制实现。
复制代码
    #include <iostream>
    using namespace std;
    
    class Animal {
    public:
    virtual void sound() {  // 声明为虚函数
        cout << "Animal sound" << endl;
    }
    };
    
    class Dog : public Animal {
    public:
    void sound() override {  // 重写父类的虚函数
        cout << "Bark" << endl;
    }
    };
    
    class Cat : public Animal {
    public:
    void sound() override {  // 重写父类的虚函数
        cout << "Meow" << endl;
    }
    };
    
    int main() {
    Animal* animal1 = new Dog();  // 父类指针指向子类对象
    Animal* animal2 = new Cat();  // 父类指针指向子类对象
    
    animal1->sound();  // 调用 Dog 类的 sound() 方法
    animal2->sound();  // 调用 Cat 类的 sound() 方法
    
    delete animal1;
    delete animal2;
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

11、模板

模板元编程(Template Metaprogramming,简称TMP)是C++中一种强大的编程技术,它允许在编译期间进行计算和类型操作。通过模板元编程,开发者可以生成高效、可复用的代码,并在编译时进行优化,实现泛型编程。

11.1、函数模板

函数模板通过建立一个通用函数,其函数返回值类型和形参类型可以不具体指定,用一个虚拟的类型来代表。

复制代码
    #基本语法
    template <typename T>
    T add(T a, T b) {
    return a + b;
    }
    #-------------------------------------#
    #                 样例                 #
    #-------------------------------------#
    #include <iostream>
    using namespace std;
    
    template <typename T>
    T add(T a, T b) {
    return a + b;
    }
    
    int main() {
    int intResult = add(2, 3);  // 传递int类型
    cout << "intResult: " << intResult << endl;
    
    double doubleResult = add(2.5, 3.7);  // 传递double类型
    cout << "doubleResult: " << doubleResult << endl;
    
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

11.2、类模板

类模板允许我们定义一个模板类,这个类可以在实例化时接受不同的类型参数。类模板的使用方式与函数模板类似。

复制代码
    #基本语法
    template <typename T>
    class Box {
    private:
    T value;
    
    public:
    Box(T v) : value(v) {}
    
    T getValue() {
        return value;
    }
    };
    
    #-------------------------------------#
    #                 样例                 #
    #-------------------------------------#
    #include <iostream>
    using namespace std;
    
    template <typename T>
    class Box {
    private:
    T value;
    
    public:
    Box(T v) : value(v) {}
    
    T getValue() {
        return value;
    }
    };
    
    int main() {
    Box<int> intBox(42);  // 实例化一个Box<int>
    cout << "Box<int>: " << intBox.getValue() << endl;
    
    Box<double> doubleBox(3.14);  // 实例化一个Box<double>
    cout << "Box<double>: " << doubleBox.getValue() << endl;
    
    return 0;
    }
    
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

12、输入/输出流与文件系统

12.1、输入\输出流

C++的标准库提供了输入流(istream)和输出流(ostream),以及它们的派生类来处理不同的输入和输出操作。
C++ 的开发者认为数据输入和输出的过程也是数据传输的过程,数据像水一样从一个地方流动到另一个地方,所以 C++ 中将此过程称为“流”,实现此过程的类称为“流类”。
在这里插入图片描述

  • istream:常用于接收从键盘输入的数据;
  • ostream:常用于将数据输出到屏幕上;
  • ifstream:用于读取文件中的数据;
  • ofstream:用于向文件中写入数据;
  • iostream:继承自 istream 和 ostream 类,因为该类的功能兼两者于一身,既能用于输入,也能用于输出;
  • fstream:兼 ifstream 和 ofstream 类功能于一身,既能读取文件中的数据,又能向文件中写入数据。

12.2、文件管理

C++通过 fstream 库提供了对文件的输入输出操作。通过文件流,程序可以从文件中读取数据,或将数据写入文件。

  • ifstream:用于从文件中读取数据(输入文件流)。
  • ofstream:用于将数据写入文件(输出文件流)。
  • fstream:用于同时进行文件的读取和写入操作(输入输出文件流)。
12.2.1、 文件读取操作 (ifstream)
复制代码
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main() {
    ifstream infile("example.txt");  // 打开文件进行读取
    if (!infile) {  // 检查文件是否成功打开
        cerr << "Failed to open the file!" << endl;
        return 1;
    }
    
    string line;
    while (getline(infile, line)) {  // 逐行读取文件内容
        cout << line << endl;
    }
    
    infile.close();  // 关闭文件
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
12.2.2、 文件写入操作 (ofstream)
复制代码
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main() {
    ofstream outfile("output.txt");  // 打开文件进行写入
    if (!outfile) {
        cerr << "Failed to open the file!" << endl;
        return 1;
    }
    
    outfile << "Hello, this is a test file!" << endl;
    outfile << "Writing to a file in C++." << endl;
    
    outfile.close();  // 关闭文件
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
12.2.3、 同时读写文件 (fstream)
复制代码
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main() {
    fstream file("example.txt", ios::in | ios::out);  // 打开文件进行读写
    if (!file) {
        cerr << "Failed to open the file!" << endl;
        return 1;
    }
    
    string line;
    while (getline(file, line)) {
        cout << "Read: " << line << endl;
    }
    
    file.seekp(0, ios::end);  // 将写入指针移动到文件末尾
    file << "Appending new content to the file." << endl;
    
    file.close();
    return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

13、异常处理

C++中的异常处理机制使用 try、throw 和 catch 来捕获和处理程序中的异常(错误)。通过这种机制,我们可以在程序运行时捕获错误并做出相应的处理,而不会导致程序直接崩溃。

  • try 块:用于包含可能抛出异常的代码。
  • throw 关键字:用于抛出异常,表示遇到错误时将异常传递出去。
  • catch 块:用于捕获抛出的异常并处理它。
复制代码
    try {
    // 可能会抛出异常的代码
    } catch (类型1& 异常变量1) {
    // 处理异常类型1
    } catch (类型2& 异常变量2) {
    // 处理异常类型2
    } catch (...) {
    // 处理其他所有类型的异常
    }
    
    
      
      
      
      
      
      
      
      
      
    

抛出异常

复制代码
    #include <iostream>
    using namespace std;
    
    void checkDivideByZero(int divisor) {
    if (divisor == 0) {
        throw "除数不能为零";  // 抛出异常
    }
    cout << "结果: " << 10 / divisor << endl;
    }
    
    int main() {
    try {
        checkDivideByZero(0);  // 触发异常
    } catch (const char* e) {
        cout << "捕获到异常: " << e << endl;  // 捕获并处理异常
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

捕获不同类型的异常

复制代码
    #include <iostream>
    using namespace std;
    
    void testExceptions() {
    throw 404;  // 抛出整数类型异常
    }
    
    int main() {
    try {
        testExceptions();  // 调用可能抛出异常的函数
    } catch (int e) {
        cout << "捕获到整数异常: " << e << endl;
    } catch (const char* e) {
        cout << "捕获到字符异常: " << e << endl;
    } catch (...) {
        cout << "捕获到未知异常" << endl;
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

异常的继承关系

复制代码
    #C++的异常类可以继承自标准异常类 std::exception。
    #这样,我们可以创建自定义异常类型,并通过继承标准异常类来获取标准异常的一些功能。
    #include <iostream>
    #include <exception>
    using namespace std;
    
    class MyException : public exception {
    public:
    const char* what() const noexcept override {
        return "自定义异常";
    }
    };
    
    void throwMyException() {
    throw MyException();  // 抛出自定义异常
    }
    
    int main() {
    try {
        throwMyException();
    } catch (const MyException& e) {
        cout << "捕获到异常: " << e.what() << endl;
    }
    return 0;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

三、总结**

整理笔记是一个二次学习的过程,许多知识点在使用中,会较易发现其潜在的发现。之后会对各个模块进行详细补充。

参考文献

[ 1 ] C语言中文网
[ 2 ] 菜鸟教程-基本数据类型
[ 3 ] C++参考手册

全部评论 (0)

还没有任何评论哟~