C++新手入门学习教程(完整版)

news2024/11/16 10:28:30

        以下教程覆盖了 C++ 学习的各个方面,适合初学者循序渐进地学习。学习过程中,建议初学者多做练习和项目,以加深对理论知识的理解。希望这个教程能为你提供一个清晰的学习路径。

目录

第一章:C++ 简介

1.1 C++ 的历史与演变

1.2 C++ 的特点和优势

1.3 C++ 的应用领域

1.4 C++ 的未来展望

第二章:环境搭建

2.1 安装 C++ 编译器与 IDE

Windows

Linux

Mac

2.2 配置开发环境

2.3 编译与运行示例程序

第三章:基本语法

3.1 C++ 程序结构

3.2 注释的使用

3.3 数据类型与变量

示例

3.4 常量与输入输出

第四章:控制结构

4.1 条件语句

if 语句示例

switch 语句示例

4.2 循环结构

for 循环示例

do-while 循环示例

第五章:函数

5.1 函数的定义与调用

5.2 参数传递方式

5.3 函数重载

5.4 默认参数与 inline 函数

5.5 Lambda表达式与函数对象

第六章:数组与字符串

6.1 一维数组与多维数组

一维数组示例

多维数组示例

6.2 字符串的处理

6.3 常用字符串函数

第七章:指针与引用

7.1 指针的概念与使用

7.2 指针与数组的关系

7.3 引用的概念与使用

7.4 指针与动态内存分配

第八章:结构体与联合体

8.1 结构体的定义与使用

8.2 结构体数组

8.3 联合体的定义与使用

8.4 枚举类型的使用

第九章:类与对象

9.1 面向对象的基本概念

9.2 类的定义与对象的创建

9.3 构造函数与析构函数

9.4 成员函数与属性

9.5 访问控制

第十章:继承与多态

10.1 继承的概念与实现

10.2 基类与派生类

10.3 虚函数与多态

10.4 多态的实现

第十一章:模板与泛型编程

11.1 函数模板

11.2 类模板

11.3 模板特化

11.4 STL(标准模板库)简介

第十二章:异常处理

12.1 异常的概念

12.2 try, catch, throw 语句

12.3 自定义异常类

示例:定义自定义异常类

代码解析

额外信息

第十三章:文件操作

13.1 文件的读写操作

示例:写入文件

示例:读取文件

13.2 二进制文件与文本文件

示例:写入二进制文件

示例:读取二进制文件

13.3 文件流的使用

示例

第十四章:标准库与命名空间

14.1 C++ 标准库概述

14.2 常用标准库函数与算法

示例:使用 vector

示例:使用 algorithm 库

14.3 命名空间的使用

第十五章:高级特性

15.1 智能指针的使用

示例:使用 std::unique_ptr

示例:使用 std::shared_ptr

15.2 Lambda 表达式与并发编程

示例:使用 Lambda 表达式

15.3 C++11/14/17/20 新特性

第十六章:综合项目

16.1 项目设计与结构

16.2 代码实现与管理

16.3 代码调试与优化

第十七章:学习资源与实践

17.1 推荐书籍

17.2 在线课程

17.3 开源项目与参与

17.4 C++ 社区与论坛

第十八章:附录

18.1 C++ 关键字

18.2 常用函数与算法汇总

18.3 参考文献


第一章:C++ 简介

1.1 C++ 的历史与演变

C++ 由 Bjarne Stroustrup 在 1979 年开始开发,最初被称为 "C with Classes",以扩展 C 语言的功能。1985 年发布了第一个完整版本,并随后的标准化过程使其不断演化。C++ 的标准化版本包括 C++98、C++03、C++11、C++14、C++17 和 C++20。

1.2 C++ 的特点和优势

  • 面向对象编程:支持封装、继承和多态,提高代码的可重用性。
  • 高效性:为系统层面的编程提供了高效的内存管理机制。
  • 标准模板库 (STL):包含丰富的算法和数据结构,极大地提高了开发效率。
  • 多范式支持:支持过程式、面向对象和泛型编程。

1.3 C++ 的应用领域

  • 系统软件:操作系统、编译器和网络系统。
  • 应用软件:桌面应用、数据库和图形用户界面。
  • 游戏开发:高性能游戏引擎,如 Unreal Engine。
  • 嵌入式系统:汽车、家电和机器人设计。

1.4 C++ 的未来展望

随着技术的不断发展,C++ 正在与时俱进,越来越多的特性(如概念和协程)正在被引入,以满足现代开发的需求。社区对于可维护性和安全性的关注也在增加。


第二章:环境搭建

2.1 安装 C++ 编译器与 IDE

Windows
  • MinGW:轻量级的编译器,简单易用。
  • Visual Studio:功能强大的 IDE,适合 Windows 开发。
Linux
  • 使用命令:sudo apt-get install g++sudo yum install gcc-c++
Mac
  • 使用 Homebrew:brew install gcc

2.2 配置开发环境

确保将编译器添加到系统路径中。可使用命令行工具或终端进行编译和运行。

2.3 编译与运行示例程序

创建一个名为 hello.cpp 的文件,内容如下:

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, C++!" << endl; // 输出 "Hello, C++!"
    return 0; // 返回 0,表示程序正常结束
}

在命令行中,使用以下命令编译并运行程序:

g++ hello.cpp -o hello
./hello

第三章:基本语法

3.1 C++ 程序结构

一个基本的 C++ 程序通常包括头文件、主函数和必要的逻辑。

3.2 注释的使用

使用注释可以提高代码的可读性。

// 这是单行注释
/* 这是多行注释
   可以跨越多行 */

3.3 数据类型与变量

数据类型

C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的

类型关键字
布尔型bool
字符型char
整型int
浮点型float
双浮点型double
无类型void
宽字符型

wchar_t

其实 wchar_t 是这样来的:

typedef short int wchar_t;

所以 wchar_t 实际上的空间是和 short int 一样。

一些基本类型可以使用一个或多个类型修饰符进行修饰:

  • signed
  • unsigned
  • short
  • long

下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。

注意:不同系统会有所差异,一字节为 8 位。

注意:默认情况下,int、short、long都是带符号的,即 signed。

注意:long int 8 个字节,int 都是 4 个字节,早期的 C 编译器定义了 long int 占用 4 个字节,int 占用 2 个字节,新版的 C/C++ 标准兼容了早期的这一设定。

类型范围
char1 个字节-128 到 127 或者 0 到 255
unsigned char1 个字节0 到 255
signed char1 个字节-128 到 127
int4 个字节-2147483648 到 2147483647
unsigned int4 个字节0 到 4294967295
signed int4 个字节-2147483648 到 2147483647
short int2 个字节-32768 到 32767
unsigned short int2 个字节0 到 65,535
signed short int2 个字节-32768 到 32767
long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int8 个字节0 到 18,446,744,073,709,551,615
float4 个字节精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double8 个字节双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字)
long long8 个字节双精度型占8 个字节(64位)内存空间,表示 -9,223,372,036,854,775,807 到 9,223,372,036,854,775,807 的范围
long double16 个字节长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。
wchar_t2 或 4 个字节1 个宽字符

注意,各种类型的存储大小与系统位数有关,但目前通用的以64位系统为主。

以下列出了32位系统与64位系统的存储大小的差别(windows 相同):

从上表可得知,变量的大小会根据编译器和所使用的电脑而有所不同。

下面实例会输出您电脑上各种数据类型的大小。

示例
#include<iostream>  
#include <limits>
 
using namespace std;  
  
int main()  
{  
    cout << "type: \t\t" << "************size**************"<< endl;  
    cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);  
    cout << "\t最大值:" << (numeric_limits<bool>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;  
    cout << "char: \t\t" << "所占字节数:" << sizeof(char);  
    cout << "\t最大值:" << (numeric_limits<char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;  
    cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);  
    cout << "\t最大值:" << (numeric_limits<signed char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;  
    cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);  
    cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;  
    cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);  
    cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;  
    cout << "short: \t\t" << "所占字节数:" << sizeof(short);  
    cout << "\t最大值:" << (numeric_limits<short>::max)();  
    cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;  
    cout << "int: \t\t" << "所占字节数:" << sizeof(int);  
    cout << "\t最大值:" << (numeric_limits<int>::max)();  
    cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;  
    cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);  
    cout << "\t最大值:" << (numeric_limits<unsigned>::max)();  
    cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;  
    cout << "long: \t\t" << "所占字节数:" << sizeof(long);  
    cout << "\t最大值:" << (numeric_limits<long>::max)();  
    cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;  
    cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);  
    cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();  
    cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;  
    cout << "double: \t" << "所占字节数:" << sizeof(double);  
    cout << "\t最大值:" << (numeric_limits<double>::max)();  
    cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;  
    cout << "long double: \t" << "所占字节数:" << sizeof(long double);  
    cout << "\t最大值:" << (numeric_limits<long double>::max)();  
    cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;  
    cout << "float: \t\t" << "所占字节数:" << sizeof(float);  
    cout << "\t最大值:" << (numeric_limits<float>::max)();  
    cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;  
    cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);  
    cout << "\t最大值:" << (numeric_limits<size_t>::max)();  
    cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;  
    cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;  
    // << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;  
    cout << "type: \t\t" << "************size**************"<< endl;  
    return 0;  
}

本实例使用了 endl,这将在每一行后插入一个换行符,<< 运算符用于向屏幕传多个值,sizeof() 运算符用来获取各种数据类型的大小。

当上面的代码被编译和执行时,它会产生以下的结果,结果会根据所使用的计算机而有所不同:

type:         ************size**************
bool:         所占字节数:1    最大值:1        最小值:0
char:         所占字节数:1    最大值:        最小值:?
signed char:     所占字节数:1    最大值:        最小值:?
unsigned char:     所占字节数:1    最大值:?        最小值:
wchar_t:     所占字节数:4    最大值:2147483647        最小值:-2147483648
short:         所占字节数:2    最大值:32767        最小值:-32768
int:         所占字节数:4    最大值:2147483647    最小值:-2147483648
unsigned:     所占字节数:4    最大值:4294967295    最小值:0
long:         所占字节数:8    最大值:9223372036854775807    最小值:-9223372036854775808
unsigned long:     所占字节数:8    最大值:18446744073709551615    最小值:0
double:     所占字节数:8    最大值:1.79769e+308    最小值:2.22507e-308
long double:     所占字节数:16    最大值:1.18973e+4932    最小值:3.3621e-4932
float:         所占字节数:4    最大值:3.40282e+38    最小值:1.17549e-38
size_t:     所占字节数:8    最大值:18446744073709551615    最小值:0
string:     所占字节数:24
type:         ************size**************

 变量类型

基本的变量类型如下:

基于前一章讲解的基本类型,有以下几种基本的变量类型,将在下一章中进行讲解:

类型描述
bool布尔类型,存储值 true 或 false,占用 1 个字节。
char字符类型,用于存储 ASCII 字符,通常占用 1 个字节。
int整数类型,通常用于存储普通整数,通常占用 4 个字节。
float

单精度浮点值,用于存储单精度浮点数。单精度是这样的格式,1 位符号,8 位指数,23 位小数,通常占用4个字节。

double

双精度浮点值,用于存储双精度浮点数。双精度是 1 位符号,11 位指数,52 位小数,通常占用 8 个字节。

void表示类型的缺失。
wchar_t宽字符类型,用于存储更大范围的字符,通常占用 2 个或 4 个字节。

C++ 也允许定义各种其他类型的变量,比如枚举、指针、数组、引用、数据结构、类等等,这将会在后续的章节中进行讲解。

  1. 整数类型(Integer Types):

    • int:用于表示整数,通常占用4个字节。
    • short:用于表示短整数,通常占用2个字节。
    • long:用于表示长整数,通常占用4个字节。
    • long long:用于表示更长的整数,通常占用8个字节。
  2. 浮点类型(Floating-Point Types):

    • float:用于表示单精度浮点数,通常占用4个字节。
    • double:用于表示双精度浮点数,通常占用8个字节。
    • long double:用于表示更高精度的浮点数,占用字节数可以根据实现而变化。
  3. 字符类型(Character Types):

    • char:用于表示字符,通常占用1个字节。
    • wchar_t:用于表示宽字符,通常占用2或4个字节。
    • char16_t:用于表示16位Unicode字符,占用2个字节。
    • char32_t:用于表示32位Unicode字符,占用4个字节。
  4. 布尔类型(Boolean Type):

    • bool:用于表示布尔值,只能取truefalse
  5. 枚举类型(Enumeration Types):

    • enum:用于定义一组命名的整数常量。
  6. 指针类型(Pointer Types):

    • type*:用于表示指向类型为type的对象的指针。
  7. 数组类型(Array Types):

    • type[]type[size]:用于表示具有相同类型的元素组成的数组。
  8. 结构体类型(Structure Types):

    • struct:用于定义包含多个不同类型成员的结构。
  9. 类类型(Class Types):

    • class:用于定义具有属性和方法的自定义类型。
  10. 共用体类型(Union Types):

    • union:用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。

在 C++ 中,类型的长度(即占用的字节数)取决于编译器和计算机架构,然而,C++ 标准规定了不同整数类型的最小范围,而不是具体的字节数,这是为了确保代码在不同的系统上都能正确运行。

请注意,以上类型的范围只是 C++ 标准规定的最小要求,实际上,许多系统上这些类型可能占用更多的字节,例如,很多现代计算机上 int 通常占用 4 字节,而 long 可能占用 8 字节。

3.4 常量与输入输出

使用 const 关键字定义常量。

const float gravity = 9.81; // 定义常量

使用 cincout 进行输入输出:

#include <iostream>
using namespace std;

int main() {
    int number;
    cout << "请输入一个数字: ";
    cin >> number; // 从用户输入读取数字
    cout << "你输入的数字是: " << number << endl; // 输出用户输入的数字
    return 0;
}

第四章:控制结构

4.1 条件语句

if 语句示例
int a = 10;
if (a > 0) {
    cout << "a 是正数" << endl; // 如果 a 大于 0
} else {
    cout << "a 不是正数" << endl; // 否则
}
switch 语句示例
int day = 4;
switch (day) {
    case 1:
        cout << "星期一" << endl;
        break;
    case 2:
        cout << "星期二" << endl;
        break;
    default:
        cout << "不是工作日" << endl;
}

4.2 循环结构

for 循环示例
for (int i = 0; i < 5; i++) {
    cout << "i 的值: " << i << endl; // 输出 i 的值
}

 while 循环示例

int j = 0;
while (j < 5) {
    cout << "j 的值: " << j << endl; // 输出 j 的值
    j++;
}
do-while 循环示例
int k = 0;
do {
    cout << "k 的值: " << k << endl; // 输出 k 的值
    k++;
} while (k < 5);

第五章:函数

5.1 函数的定义与调用

函数用于将代码逻辑模块化,便于重用。

int add(int a, int b) {
    return a + b; // 返回 a 和 b 的和
}

int main() {
    int result = add(5, 3); // 调用函数
    cout << "5 + 3 = " << result << endl;
    return 0;
}

5.2 参数传递方式

  • 值传递:将参数的副本传递给函数。
  • 引用传递:将参数的引用传递给函数(可以修改原变量)。
    void modify(int &num) {
        num += 10; // 修改引用参数
    }
    
    int main() {
        int x = 5;
        modify(x);
        cout << "x 的值: " << x << endl; // 输出 15
        return 0;
    }
    

    5.3 函数重载

    允许同名函数,但参数类型或数量不同。

    float multiply(float a, float b) {
        return a * b;
    }
    
    int multiply(int a, int b) {
        return a * b;
    }
    

    5.4 默认参数与 inline 函数

  • 默认参数示例:
    void greet(string name = "World") {
        cout << "Hello, " << name << "!" << endl;
    }
    

    inline 函数示例:

    inline int square(int x) {
        return x * x;
    }
    

    5.5 Lambda表达式与函数对象

    使用 lambda 表达式定义简单的函数。

    auto add = [](int a, int b) {
        return a + b;
    };
    
    cout << "Lambda add: " << add(5, 3) << endl; // 输出 8
    

    第六章:数组与字符串

    6.1 一维数组与多维数组

    一维数组示例
    int arr[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " "; // 输出数组元素
    }
    
    多维数组示例
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            cout << matrix[i][j] << " "; // 输出矩阵元素
        }
    }
    

    6.2 字符串的处理

  • C 风格字符串:以 \0 结尾的字符数组。
  • C++ 字符串:使用 std::string
    #include <string>
    
    string str = "Hello, World!";
    cout << "字符串长度: " << str.length() << endl; // 输出字符串长度
    

    6.3 常用字符串函数

    string str = "Hello";
    str += " World"; // 连接字符串
    cout << str << endl; // 输出 "Hello World"
    

    第七章:指针与引用

    7.1 指针的概念与使用

    指针是存储变量地址的变量。

    int a = 10;
    int *p = &a; // p 存储 a 的地址
    cout << "a 的值: " << *p << endl; // 输出 10
    

    7.2 指针与数组的关系

    数组名代表数组的首地址,可以用指针访问数组元素。

    int arr[3] = {1, 2, 3};
    int *p = arr; // 等价于 int *p = &arr[0];
    cout << *(p + 1) << endl; // 输出 2
    

    7.3 引用的概念与使用

    引用是变量的别名。

    int b = 20;
    int &r = b; // r 是 b 的引用
    r = 30; // 修改 r 也会修改 b
    cout << "b 的值: " << b << endl; // 输出 30
    

    7.4 指针与动态内存分配

    使用 newdelete 进行动态内存管理。

    int *ptr = new int; // 动态分配内存
    *ptr = 42;
    cout << "动态内存中的值: " << *ptr << endl;
    delete ptr; // 释放内存
    

    第八章:结构体与联合体

    8.1 结构体的定义与使用

    结构体用于将不同类型的数据组合在一起。

    struct Person {
        string name;
        int age;
    };
    
    Person p;
    p.name = "Alice";
    p.age = 30;
    cout << "姓名: " << p.name << ", 年龄: " << p.age << endl;
    

    8.2 结构体数组

    创建结构体数组以存储多个结构体实例。

    Person people[2] = {{"Alice", 30}, {"Bob", 25}};
    for (int i = 0; i < 2; i++) {
        cout << "姓名: " << people[i].name << ", 年龄: " << people[i].age << endl;
    }
    

    8.3 联合体的定义与使用

    联合体用于节省内存,所有成员共享相同的内存。

    union Data {
        int intValue;
        float floatValue;
    };
    
    Data data;
    data.intValue = 10;
    cout << "整数值: " << data.intValue << endl;
    data.floatValue = 5.5; // 修改 floatValue 会影响 intValue 的值
    cout << "浮点值: " << data.floatValue << endl;
    

    8.4 枚举类型的使用

    枚举用于定义一组命名的整数常量。

    enum Color { RED, GREEN, BLUE };
    Color c = GREEN;
    cout << "选择的颜色值: " << c << endl; // 输出 1
    

    第九章:类与对象

    9.1 面向对象的基本概念

    类是对象的蓝图,对象是类的实例。

    9.2 类的定义与对象的创建

    class Car {
    public:
        string brand;
        int year;
        
        void display() {
            cout << "品牌: " << brand << ", 年份: " << year << endl;
        }
    };
    
    int main() {
        Car myCar;
        myCar.brand = "Toyota";
        myCar.year = 2020;
        myCar.display();
        return 0;
    }
    

    9.3 构造函数与析构函数

    构造函数用于初始化对象,析构函数用于清理资源。

    class Point {
    public:
        int x, y;
        
        Point(int xVal, int yVal) : x(xVal), y(yVal) {} // 构造函数
        ~Point() {} // 析构函数
    };
    
    Point p(10, 20); // 创建对象时调用构造函数
    

    9.4 成员函数与属性

    类的成员函数可以访问和修改类的属性。

    class Circle {
    public:
        double radius;
        
        double area() {
            return 3.14 * radius * radius; // 计算面积
        }
    };
    
    Circle c;
    c.radius = 5;
    cout << "圆的面积: " << c.area() << endl; // 输出 78.5
    

    9.5 访问控制

    C++ 提供了三种访问控制:public、private、protected。

    class Box {
    private:
        double width; // 私有属性
        
    public:
        void setWidth(double w) {
            width = w; // 通过公有方法访问私有属性
        }
        
        double getWidth() {
            return width;
        }
    };
    

    第十章:继承与多态

    10.1 继承的概念与实现

    继承允许一个类从另一个类派生,重用代码。

    class Animal {
    public:
        void eat() {
            cout << "Eating..." << endl;
        }
    };
    
    class Dog : public Animal { // Dog 继承 Animal
    public:
        void bark() {
            cout << "Barking..." << endl;
        }
    };
    
    int main() {
        Dog d;
        d.eat(); // 调用基类方法
        d.bark(); // 调用派生类方法
        return 0;
    }
    

    10.2 基类与派生类

    基类提供公共接口,派生类扩展或修改基类的行为。

    10.3 虚函数与多态

    虚函数允许在派生类中重写基类的方法。

    class Base {
    public:
        virtual void show() { // 虚函数
            cout << "Base class" << endl;
        }
    };
    
    class Derived : public Base {
    public:
        void show() override { // 重写
            cout << "Derived class" << endl;
        }
    };
    
    int main() {
        Base* b = new Derived();
        b->show(); // 输出 "Derived class"
        delete b;
        return 0;
    }
    

    10.4 多态的实现

    通过基类指针调用派生类的重写方法。

    Base* basePtr = new Derived();
    basePtr->show(); // 输出 "Derived class"
    delete basePtr;
    

    第十一章:模板与泛型编程

    11.1 函数模板

    函数模板允许编写可以处理不同数据类型的函数。

    template <typename T>
    T add(T a, T b) {
        return a + b;
    }
    
    int main() {
        cout << "int: " << add(5, 10) << endl; // 输出 15
        cout << "double: " << add(5.5, 3.5) << endl; // 输出 9.0
        return 0;
    }
    

    11.2 类模板

    类模板允许定义可以处理不同数据类型的类。

    template <typename T>
    class Pair {
    private:
        T first, second;
    public:
        Pair(T a, T b) : first(a), second(b) {}
        T getFirst() { return first; }
        T getSecond() { return second; }
    };
    
    int main() {
        Pair<int> p(10, 20);
        cout << "First: " << p.getFirst() << ", Second: " << p.getSecond() << endl;
        return 0;
    }
    

    11.3 模板特化

    可以为特定类型创建模板特化。

    template <>
    class Pair<string> {
    private:
        string first, second;
    public:
        Pair(string a, string b) : first(a), second(b) {}
        string getConcatenated() { return first + second; }
    };
    
    int main() {
        Pair<string> p("Hello", " World");
        cout << "Concatenated: " << p.getConcatenated() << endl;
        return 0;
    }
    

    11.4 STL(标准模板库)简介

    STL 提供了许多通用数据结构和算法,如 vector, list, map, set 等。

    #include <vector>
    
    int main() {
        vector<int> vec = {1, 2, 3, 4, 5};
        for (int num : vec) {
            cout << num << " "; // 输出 1 2 3 4 5
        }
        return 0;
    }
    

    第十二章:异常处理

    12.1 异常的概念

    异常处理用于处理运行时错误,确保程序的稳定性。

    12.2 try, catch, throw 语句

    使用 try 块捕获异常,使用 catch 块处理异常。

    try {
        throw runtime_error("发生错误");
    } catch (const runtime_error& e) {
        cout << "捕获到异常: " << e.what() << endl; // 输出异常信息
    }
    

    12.3 自定义异常类

    在 C++ 中,你可以根据需要自定义异常类,以提供更具体的错误信息,增强程序的可读性和可维护性。自定义异常类通常继承自 std::exception 类,并重写 what() 方法,以提供错误描述。

    示例:定义自定义异常类
    #include <iostream>
    #include <exception>
    #include <string>
    
    using namespace std;
    
    // 自定义异常类,继承自 std::exception
    class MyException : public std::exception {
    private:
        string message; // 错误信息
    
    public:
        // 构造函数
        MyException(const string& msg) : message(msg) {}
    
        // 重写 what() 方法
        virtual const char* what() const noexcept override {
            return message.c_str(); // 返回错误信息
        }
    };
    
    // 函数,可能会抛出异常
    void riskyFunction(int value) {
        if (value < 0) {
            throw MyException("负数错误:不能为负数"); // 抛出自定义异常
        }
        cout << "输入的值是: " << value << endl;
    }
    
    int main() {
        try {
            riskyFunction(-1); // 调用可能抛出异常的函数
        } catch (const MyException& e) {
            cout << "捕获到异常: " << e.what() << endl; // 输出异常信息
        } catch (const std::exception& e) {
            cout << "捕获到标准异常: " << e.what() << endl;
        }
    
        return 0;
    }
    
    代码解析
  • 自定义异常类 MyException

    • 继承自 std::exception 类。
    • 在构造函数中接受一个字符串参数,表示错误信息。
    • 重写 what() 方法,返回错误信息字符串。
  • 函数 riskyFunction

    • 接受一个整数参数。
    • 如果参数小于 0,则抛出 MyException 异常。
  • 主函数

    • 使用 try 块调用 riskyFunction
    • 如果抛出 MyException 异常,使用 catch 块捕获并处理异常,打印出异常信息。
额外信息
  • 异常安全性:在设计代码时,确保在抛出异常时不会导致资源泄漏或不一致的状态。使用 RAII(资源获取即初始化)技术可以帮助管理资源。
  • 异常层次结构:可以创建更复杂的异常层次结构,允许捕获不同类型的异常,提供更详细的错误处理机制。

通过自定义异常类,您可以为程序中的错误和异常情况提供更清晰和更具体的处理方式。这种方法可以提高代码的可读性,并使调试过程更容易。

第十三章:文件操作

13.1 文件的读写操作

示例:写入文件
#include <fstream>
#include <iostream>
using namespace std;

int main() {
    ofstream outFile("example.txt"); // 创建输出文件流
    if (outFile.is_open()) {
        outFile << "Hello, file!" << endl; // 写入内容
        outFile.close(); // 关闭文件
    } else {
        cout << "无法打开文件进行写入。" << endl;
    }
    return 0;
}
示例:读取文件
#include <fstream>
#include <iostream>
using namespace std;

int main() {
    ifstream inFile("example.txt"); // 创建输入文件流
    string line;

    if (inFile.is_open()) {
        while (getline(inFile, line)) { // 按行读取文件
            cout << line << endl; // 输出每一行
        }
        inFile.close(); // 关闭文件
    } else {
        cout << "无法打开文件进行读取。" << endl;
    }
    return 0;
}

13.2 二进制文件与文本文件

  • 文本文件:以人类可读的格式存储数据。
  • 二进制文件:以二进制格式存储数据,通常用于高效存储和读取。
示例:写入二进制文件
#include <fstream>
using namespace std;

int main() {
    ofstream outFile("binary.dat", ios::binary); // 创建二进制输出文件流
    int num = 42;
    outFile.write(reinterpret_cast<char*>(&num), sizeof(num)); // 写入整数
    outFile.close();
    return 0;
}
示例:读取二进制文件
#include <fstream>
#include <iostream>
using namespace std;

int main() {
    ifstream inFile("binary.dat", ios::binary); // 创建二进制输入文件流
    int num;
    inFile.read(reinterpret_cast<char*>(&num), sizeof(num)); // 读取整数
    cout << "读取的数: " << num << endl;
    inFile.close();
    return 0;
}

13.3 文件流的使用

C++ 提供 fstream,用于同时读取和写入文件。

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

int main() {
    fstream file("example.txt", ios::in | ios::out | ios::app); // 以读写模式打开文件
    if (file.is_open()) {
        file << "追加内容!" << endl; // 追加内容
        file.seekg(0); // 将文件指针移到文件开头
        string line;
        while (getline(file, line)) { // 读取文件内容
            cout << line << endl;
        }
        file.close(); // 关闭文件
    }
    return 0;
}

第十四章:标准库与命名空间

14.1 C++ 标准库概述

C++ 标准库包含了丰富的函数、类和模板,极大地提高了开发效率。常用的 STL 组件有容器、算法和迭代器。

14.2 常用标准库函数与算法

示例:使用 vector
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    vec.push_back(6); // 添加元素
    for (int num : vec) {
        cout << num << " "; // 输出每个元素
    }
    cout << endl;
    return 0;
}
示例:使用 algorithm
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main() {
    vector<int> vec = {5, 3, 1, 4, 2};
    sort(vec.begin(), vec.end()); // 排序
    for (int num : vec) {
        cout << num << " "; // 输出已排序的元素
    }
    cout << endl;
    return 0;
}

14.3 命名空间的使用

命名空间用于组织代码,避免命名冲突。

namespace MyNamespace {
    void display() {
        cout << "Hello from MyNamespace!" << endl;
    }
}

int main() {
    MyNamespace::display(); // 调用命名空间中的函数
    return 0;
}

第十五章:高级特性

15.1 智能指针的使用

智能指针自动管理内存,减少内存泄漏的风险。

示例:使用 std::unique_ptr
#include <iostream>
#include <memory>
using namespace std;

int main() {
    unique_ptr<int> ptr(new int(10)); // 创建智能指针
    cout << "值: " << *ptr << endl; // 输出值
    // 不需要手动 delete,ptr 超出作用域后会自动释放内存
    return 0;
}
示例:使用 std::shared_ptr
#include <iostream>
#include <memory>
using namespace std;

int main() {
    shared_ptr<int> p1(new int(20)); // 创建共享指针
    {
        shared_ptr<int> p2 = p1; // 共享所有权
        cout << "值: " << *p2 << endl; // 输出值
    } // p2 超出作用域后不会释放内存,p1 仍然存在
    cout << "值: " << *p1 << endl; // 输出值
    return 0;
}

15.2 Lambda 表达式与并发编程

Lambda 表达式用于简化函数对象的定义,适合回调和并行执行。

示例:使用 Lambda 表达式
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    for_each(vec.begin(), vec.end(), [](int n) {
        cout << n << " "; // 输出每个元素
    });
    cout << endl;
    return 0;
}

15.3 C++11/14/17/20 新特性

  • C++11:引入了 auto 关键字、范围 for 循环、nullptr、线程库等。
  • C++14:改进了 lambda 表达式,支持泛型 lambda。
  • C++17:引入了结构化绑定、if constexpr、std::optional 等。
  • C++20:引入了概念(concept)、范围(ranges)等。

第十六章:综合项目

16.1 项目设计与结构

设计一个小型项目,定义功能模块与类结构,使用面向对象的设计原则。

16.2 代码实现与管理

使用版本控制工具(如 Git)管理代码,记录每次更新。

16.3 代码调试与优化

使用调试工具(如 GDB 或 IDE 内置调试工具)进行调试,分析性能瓶颈并进行优化。


第十七章:学习资源与实践

17.1 推荐书籍

  • 《C++ Primer》 - Stanley B. Lippman
  • 《Effective C++》 - Scott Meyers
  • 《The C++ Programming Language》 - Bjarne Stroustrup
  • 《高质量程序设计指南-C++\C语言》第三版

17.2 在线课程

  • Coursera、edX、Udacity 等平台的 C++ 课程。
  • B站的编程教程频道。

17.3 开源项目与参与

参与 GitHub 上的 C++ 开源项目,学习最佳实践,提升编程能力。

17.4 C++ 社区与论坛

加入 C++ 相关的社区与讨论组(如 Stack Overflow、Reddit 的 C++ 版块),向他人学习。


第十八章:附录

18.1 C++ 关键字

列出 C++ 中的所有关键字,比如 class, public, private, virtual, template 等。

18.2 常用函数与算法汇总

  • 排序:sort()
  • 查找:find()
  • 复制:copy()
  • 变换:transform()

18.3 参考文献

  • C++ 标准文档
  • 各大编程网站的相关教程与文档。

        这个C++ 学习教程,可以帮助初学者系统地掌握 C++ 语言的基础与进阶知识,同时提供了丰富的示例和练习,结合项目实践,有助于巩固所学的知识。希望对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1981826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低代码: 系统开发准备之确定一般开发流程,需求分析,技术架构

概述 低代码系统开发之前&#xff0c;我们首先要进行一些准备我们首先知道我们软件开发的一般流程同时&#xff0c;我们还要知道&#xff0c;我们整个系统平台的需求如何之后&#xff0c;我们要基于需求进行设计&#xff0c;包含UI设计与系统架构设计 一般开发流程 系统开发…

数据库典型例题1-画ER图

1.question: solution: 2.画图步骤&#xff1a; 1.圈实体 2.写出实体间关系&#xff0c;确定实体画图位置 3.圈出每个实体的属性 4.画图&#xff0c;注意特殊实体和属性 3.注意点 <1 弱实体 弱实体&#xff1a;一个实体必须依赖于另一个实体存在---->实体双线菱形弱…

centos Python3.6升级3.8

CentOS系统上升级Python3.6到3.8版本。 步骤 1. 更新系统 在开始升级Python之前&#xff0c;首先需要确保系统是最新的。可以使用以下命令更新CentOS系统&#xff1a; sudo yum update 2. 安装依赖项 升级Python之前&#xff0c;需要安装一些依赖项。运行以下命令安装这些依赖…

Common Lisp精解【1】

文章目录 概述什么是 Common Lisp概念历史 应用领域1. 人工智能2. 自然语言处理3. 数据分析4. 系统编程5. Web开发6. 教育与研究7. 其他领域 基础 参考文献 概述 以下内容来自文心一言的自动生成 什么是 Common Lisp Common Lisp&#xff08;缩写为CL&#xff09;是Lisp编程语…

Unity使用Modbus协议

最近一直在工业领域干活&#xff0c;学习下Modbus协议&#xff0c;这里做个记录&#xff0c;理解不对的地方希望大佬指出修正。 一、先上测试工具和Unity脚本。 1.测试工具使用的 Modsim32 2.Unity测试脚本如下 /* 0x01&#xff1a;读线圈 0x05&#xff1a;写单个线圈 0x0F…

计算机组成原理 —— 指令流水线影响因素分类

计算机组成原理 —— 指令流水线影响因素分类 结构冒险结构冒险的原因 数据冒险&#xff08;同步&#xff09;数据旁路的原理数据旁路的类型数据旁路的例子 控制冒险控制冒险的类型控制冒险的例子解决控制冒险的方法示例分析分支预测的策略 超标量和超流水超标量&#xff08;Su…

关于计算机的思考

本文是《Python入门经典以解决计算问题为导向的Python编程实践》一书中第一部分“关于计算机的思考”的笔记&#xff0c;后附上思维导图。 关于计算机的思考 一、为什么要研究计算机科学1、重要性2、“计算机科学”更强调计算而不是编程3、从”通过编程解决问题“的思路出发&a…

RPC通信的简单流程

远程调用者假设需要调用Login方法&#xff0c;将调用的信息通过muduo库&#xff0c;同时进行了序列化和反序列化&#xff0c;发送到Rpcprovider上&#xff0c;RpcProvider通过对象和方法表来确定需要调用哪个服务对象的哪个方法。 UserRpcServiceRpc和UseRpcServiceRpcStub是继…

去中心化社交:探讨Facebook在区块链平台上的实践

随着区块链技术的崛起&#xff0c;社交平台也面临着前所未有的变革。作为全球最大的社交平台之一&#xff0c;Facebook&#xff08;现名Meta Platforms&#xff09;正在积极探索如何将区块链技术融入其平台&#xff0c;以引领去中心化社交的新时代。本文将从不同角度探讨Facebo…

leaflet.motion台风路径动画绘制

在气象领域中&#xff0c;对台风的准确可视化呈现对于灾害预警和防范具有重要意义。本文将深入探讨一段使用 JavaScript 实现台风可视化功能的代码。原本只是简单的绘制台风的路径&#xff0c;但是后面的需求要求显示台风各个历史节点的动画绘制&#xff0c;于是难度增加了&…

《安全历史第4讲——从古代驿站体系看软件安全管控》

在古代&#xff0c;车、马都很慢&#xff0c;信息传递很不顺畅&#xff0c;中央的政令又是如何传达至地方的呢&#xff1f;实际上&#xff0c;很多朝代都有专门的驿站制度&#xff0c;可以保障全国各地的信息传递&#xff0c;对于维护统治和稳定有着关键作用。 若将国家比作一个…

OZON刚需产品哪些好卖,OZON刚需热卖产品

OZON平台上的刚需热卖产品涵盖了多个领域&#xff0c;这些产品通常能够满足消费者的基本需求或提升生活品质。以下是一些在OZON平台上表现良好的刚需热卖产品类别及其特点&#xff01; OZON刚需热卖产品地址&#xff1a;D。DDqbt。COm/74rDTop1 防蚊修复网 Скотч сет…

二次注入(2018网鼎杯comment)

一、2018网鼎杯comment 该题主要考察二次注入 1.二次注入概念&#xff1a; 攻击者构造恶意的数据并存储在数据库后&#xff0c;恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理&#xff0c;但在恶意数据插入…

【LeetCode Cookbook(C++ 描述)】一刷二叉树之递归遍历(DFS)(上)

目录 二叉树的实现LeetCode #144&#xff1a;Binary Tree Preorder Traversal 二叉树的前序遍历递归解法「遍历」思路「分而治之」思路更多例子&#xff1a;求二叉树最大深度 迭代解法Morris 遍历 LeetCode #94&#xff1a;Binary Tree Inorder Traversal 二叉树的中序遍历迭代…

亲民且友好的Top期刊,最快46天录用!

本期小编解析一本超亲民超友好的Top期刊&#xff0c;发文量大&#xff0c;编辑处理速度极快&#xff08;近期案例46天录用&#xff09;&#xff0c;毕业有高分区发文要求的小伙伴&#xff0c;赶紧码住这一本神刊&#xff01; 期刊简介 Knowledge-Based Systems (KBS) 出版社 …

AI智能测评应用平台项目分享

大家好&#xff0c;我是程序媛雪儿&#xff0c;今天咱们聊个我新学的项目&#xff0c;AI智能评测应用平台系统。 咱们先了解一下这个系统是干嘛的。 一、业务分析 大致业务流程是应用制作者在创建应用页面填写应用信息&#xff0c;依次添加题目和评分规则生成测评应用&#xff…

信息学奥赛初赛天天练-56-CSP-J2019完善程序2-双关键字排序、计数排序、前缀和、前缀自增、后缀自增、数组下标自增

PDF文档公众号回复关键字:20240805 1 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) 计数排序 计数排序是一个广泛使用的排序方法。下面的程序使用双关键字计数排序&#xff0c;将 n 对 10000以内的整数&#xff0c;从小到大排序。 例如有三对整数 (3,4)、(2,…

标准IO及相关练习

标准IO 能够将指定的数据写入指定的文件中的操作&#xff08;通过文件指针去访问指定的文件&#xff1a;FILE*&#xff09;&#xff0c;标注IO只提供写入或者读取操作&#xff0c;不提供删除文件中的内容&#xff0c;想要删除文件&#xff0c;则需要自己写逻辑来实现。 文件指…

【LeetCode Cookbook(C++ 描述)】一刷哈希表(Hash Table)(下)

目录 LeetCode #349&#xff1a;Intersection of Two Arrays 两个数组的交集LeetCode #383&#xff1a;Ransom Note 赎金信LeetCode #454&#xff1a;4Sum II - 四数相加 II 本系列文章仅是 GitHub 大神 halfrost 的刷题笔记 《LeetCode Cookbook》的提纲以及示例、题集的 C转化…

办公楼子母钟系统,不止显示时间,还可以做临时告示牌

在现代办公环境中&#xff0c;时间管理对于提高工作效率至关重要。传统的时钟往往只能提供最基本的时间显示功能&#xff0c;而在快节奏的办公楼里&#xff0c;一个既能准确显示时间又能发布紧急通知的系统显得尤为必要。本文将介绍办公楼子母钟系统的独特优势及其在不同场景中…