CPP学习笔记—结构化绑定
1. 什么是结构化绑定?一句话概括: 结构化绑定是一种允许你用一个声明语句,将一个对象(如 struct、class、std::tuple、std::pair 或 C 风格数组)的多个成员或元素,一次性解构并绑定到多个独立变量上的语法。 它的核心目的是提升代码的可读性和简洁性,消除访问复合对象成员时的冗余代码。 核心语法: 123auto [ a, b, c, ... ] = some_object;// or with qualifiers:const auto& [ a, b, c, ... ] = some_object; auto: 关键字,表示类型推导,必须使用 auto(或 auto&, auto&&, const auto& 等)。 [...]: 方括号内是用逗号分隔的新变量名列表。 = some_object: 等号右边是需要被解构的对象。 2. 为什么需要结构化绑定?(The “Why”)在 C++17 之前,当我们处理返回多个值的函数(通常通过 std::pair 或 std::tuple)或遍历一个...
CPP学习笔记—策略模式
1. 什么是策略模式?策略模式是一种行为设计模式,它定义了一系列算法,将每一个算法封装起来,并使它们可以相互替换。此模式让算法的变化独立于使用算法的客户。 简单来说,策略模式的核心思想是: 分离: 将算法的 定义(是什么) 与算法的 使用(何时用) 分离开来。 封装: 将不同的算法(即“策略”)封装在各自独立的类中。 委托: “上下文”(Context)对象不亲自执行算法,而是将任务委托给它所持有的策略对象。 GoF(《设计模式》)中的经典定义是:“Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.” 2. 为什么需要策略模式?(问题场景)假设我们正在编写一个数据处理程序,其中一个功能是对一组数据进行排序。一开始,我们可能只实现了一种排序算法,比如冒泡排序。 一个反例:使用 if-else 或...
CPP学习笔记—std::function的用法
std::function 是 C++11 中引入的一个极其有用的工具,位于 <functional> 头文件中。它是一个通用的、多态的函数包装器。它的实例可以存储、复制和调用任何可调用 (Callable) 目标——包括普通函数、Lambda 表达式、函数指针、成员函数指针、以及函数对象(functors)。 1. std::function 是什么?一句话定义std::function 是一个类型安全的包装器,它可以持有任何符合其函数签名的可调用对象。 可以把它想象成一个“万能的函数指针”,但它比函数指针强大得多,因为它可以指向任何可调用的东西,而不仅仅是全局函数。 解决的问题:类型不统一的“可调用物”在 C++ 中,有很多东西都可以被“调用”,比如: 普通函数指针: void (*p_func)(int); 函数对象 (Functor): 一个重载了 operator() 的类的对象。每个函数对象都有自己独特的类型。 Lambda 表达式: 编译器会为每个 Lambda 生成一个唯一的、匿名的闭包类型。 在 std::function...
CPP学习笔记—右值引用和移动语义
右值引用(Rvalue Reference)和移动语义(Move Semantics)是 C++11 中引入的最重要的特性之一,它极大地提升了 C++ 的性能,并使得一些新的编程范式(如资源所有权的唯一性)成为可能。 1. 背景知识:左值(Lvalue)与右值(Rvalue)在 C++ 中,每一个表达式都有两个属性:类型(Type) 和 值类别(Value Category)。值类别中最基本的就是左值和右值。 左值 (Lvalue - Locator Value)可以把它粗略地理解为 “有固定内存地址、可以被赋值” 的表达式。它就像一个有名字、有固定住址的“居民”。 特征: 可以取地址(使用 & 运算符)。 通常出现在赋值运算符 = 的左边。 在表达式结束后依然存在。 例子: 变量名:int x = 10; (x 是一个左值)。 数组元素:arr[0]。 解引用的指针:*p。 返回左值引用的函数调用:get_string_ref()。 右值 (Rvalue - Read Value)可以把它粗略地理解为 “临时的、即将被销毁”...
CPP学习笔记—现代C++的特性
C++11 被认为是 C++ 语言的一次重生,标志着“现代 C++”的开端。后续的标准则在这个基础上不断完善、增强和现代化。 一、 C++11:现代 C++ 的基石C++11 是一次巨大的飞跃,引入了大量深刻影响 C++ 编程范式的特性。 1. 语言核心增强 (提升易用性和表达力) auto 关键字: 是什么:自动类型推导。编译器可以根据变量的初始化表达式自动推导出其类型。 为什么需要:避免编写冗长、复杂的类型名,特别是对于 STL 迭代器和模板类型。 示例:1234// 旧式std::vector<int>::iterator it = my_vector.begin();// C++11auto it_new = my_vector.begin(); // 自动推导为 std::vector<int>::iterator nullptr: 是什么:一个类型安全的空指针常量,类型为 std::nullptr_t。 为什么需要:解决了旧 NULL (通常是 0 或 (void*)0)...
CPP学习笔记—模板
一、 什么是C++模板 (What are C++ Templates?)C++模板是 泛型编程(Generic Programming) 的核心工具。它允许我们编写与类型无关的代码,即编写一份代码,可以用于多种不同的数据类型。 可以把模板想象成一个 “代码的蓝图”或“配方” 。它本身并不是一个可以直接运行的函数或类,而是一个指令,告诉编译器如何根据我们提供的具体类型(如 int, double, std::string 或自定义类)来生成一个特定版本的函数或类。 这个在编译时根据模板生成具体类型代码的过程,称为模板实例化(Template Instantiation)。 二、 为什么需要模板 (Why Do We Need Templates?)假设我们要写一个交换两个整数值的函数: 12345void swap_int(int& a, int& b) { int temp = a; a = b; b = temp;} 如果现在还需要交换两个 double 或 string...
Linux命令
第一部分:Linux 命令行的基石在开始学习具体命令之前,理解几个核心概念至关重要。 1. 什么是 Shell?你输入的命令并不是由 Linux 内核直接处理的。你是在和一个叫做 Shell 的程序交互。Shell 是一个命令解释器,它接收你输入的命令,解释它们,然后请求操作系统(Linux 内核)来执行。 常见的 Shell: bash (Bourne Again SHell):绝大多数 Linux 发行版的默认 Shell。 zsh (Z Shell):功能更强大,配置更灵活,是很多开发者的最爱。 fish (Friendly Interactive SHell):开箱即用,有很好的自动补全和语法高亮功能。 本介绍将以最常见的 bash 为例。 2. 命令的基本结构一个典型的 Linux 命令遵循以下结构: 1command [options] [arguments] command (命令):你要执行的程序的名称,例如 ls, cp, mkdir。 options (选项/标志):用来修改命令的行为。通常以一个或两个破折号 (- 或 --)...
I/O多路复用
I/O 多路复用(I/O Multiplexing)是一种在计算机网络编程中至关重要的技术,也是构建高性能服务器的基石。 1. 背景:为什么需要 I/O 多路复用?想象一下你要开发一个网络服务器,需要同时处理多个客户端的连接。我们来看看几种最原始的模型以及它们的缺陷。 模型一:阻塞 I/O + 多进程/多线程这是最直观的模型。主进程负责监听(listen)新的连接请求。每当有一个新的客户端连接进来(accept),服务器就创建一个新的进程或线程专门为这个客户端服务。 工作流程: 主线程/进程 accept() 等待新连接,阻塞。 新连接到达,accept() 返回一个新的socket文件描述符(fd)。 创建一个子线程/进程,将这个新的fd交给它处理。 子线程/进程在这个fd上调用 read()/recv(),等待客户端发送数据,阻塞。 数据到达,read() 返回,处理数据,然后可能调用...
零拷贝
摘要:什么是零拷贝?零拷贝(Zero-Copy) 并不是指完全没有数据拷贝,而是指尽可能地减少或避免在应用程序的用户空间(User Space)和操作系统的内核空间(Kernel Space)之间进行不必要的CPU数据拷贝。其核心目标是让数据在从一个I/O设备(如硬盘)到另一个I/O设备(如网卡)的传输过程中,最大限度地利用硬件(如DMA)来搬运数据,从而解放CPU,减少上下文切换,显著提升数据传输的性能和效率。 一、 理解背景:传统I/O的痛点要理解零拷贝的价值,我们必须先了解传统的数据传输方式有多么“昂贵”。 假设我们要实现一个简单的文件服务器,其功能是:从磁盘读取一个文件,然后通过网络发送给客户端。 传统I/O的操作流程: 我们用代码来看,通常是这样的: 12read(file_fd, buffer, len);write(socket_fd, buffer, len); 这个看似简单的两行代码,在操作系统层面会触发一系列复杂的步骤: 第一次拷贝(DMA Copy): 应用程序调用 read()...
正则表达式与模式匹配
第一部分:正则表达式(Regular Expression)详解1. 什么是正则表达式?正则表达式是一种描述字符模式的对象。可以把它想象成一种极其强大的“查找和替换”工具,它不是用固定的字符(如 “abc”)去查找,而是用一种描述性的语言(如 “查找三个数字”)去匹配一系列符合某个句法规则的字符串。 它的核心用途包括: 数据验证:检查输入的数据是否符合某种格式(如邮箱、手机号、身份证号)。 文本搜索与定位:在大量文本中快速找到符合特定模式的内容。 文本提取:从一段文本中抽取出需要的信息(如网页爬虫中提取标题和链接)。 文本替换:将符合模式的文本替换成其他内容。 2. 核心组成元素(元字符 Metacharacters)正则表达式的威力来自于它的特殊字符——元字符。普通字符(如 a, b, 1, 2)在正则中就是匹配它们自身,而元字符则有特殊的含义。 2.1 基础字符与预定义字符集 元字符 描述 示例 . 匹配除换行符 \n 之外的任意单个字符 a.c 匹配 “abc”, “a_c”, “a2c” \d 匹配任意一个数字(等价于 [0-9]) \d{3} 匹配...










