函数模板
代码仓库shanchuann/CPP-Learninng 函数模板被称为”生成代码的代码”,是 C++ 通用编程的核心工具,它通过参数化类型定义一族函数的蓝图,编译时会根据实际使用的类型 / 值自动生成具体函数实例,无需为每种场景重复编写相同逻辑,大幅提升代码复用性与扩展性。 函数模板的声明 / 定义需遵循特定语法,C++ 标准演进中新增了简化语法,同时废弃了部分特性,核心语法分为以下几类: 函数模板的语法标准语法(C++98 起)基础语法通过template关键字声明模板参数列表,后接函数声明 / 定义,适用于所有 C++ 标准。 123456789101112// 语法格式:template <参数列表> 函数声明/定义template <typename T> // T为类型模板参数,typename可替换为classT max(T a, T b) { return a > b ? a : b;}template <int N, typename T> // ...
命名空间namespace
代码仓库shanchuann/CPP-Learninng 在C++中支持三种域:局部域,命名空间域,类域 在 C++ 大型项目开发中,不同模块、库或开发者定义的同名变量、函数、类很容易引发 “名称冲突”。命名空间(namespace)作为 C++ 的核心特性之一,通过划分 “名称作用域”,为解决全局变量的命名污染问题,全局标识符的污染问题提供解决方案。 12345678910111213141516int Global_scope = 10; //全局作用域void Local_scope() { int Local_scope = 20; //局部作用域 { int Block_scope = 30; //块作用域 cout << "Block_scope: " << Block_scope << endl; cout << "Local_scope: " << Local_scope << endl; cout <&l...
名字粉碎
代码仓库shanchuann/CPP-Learninng 名字粉碎(Name Mangling,也称为名字修饰) 是编译器为解决命名冲突(如函数重载、类成员、命名空间、模板等场景)而对标识符(函数名、变量名等)进行的特殊编码处理。其核心目的是生成唯一的符号名,确保链接阶段能准确识别不同的实体。 C 语言不支持函数重载、类、命名空间等特性,函数名本身即可唯一标识一个函数,因此无需修饰。但 C++ 支持以下特性,会导致同名实体存在,必须通过名字粉碎区分: 函数重载:允许同名函数存在,只要参数列表不同(参数类型、数量、顺序); 类成员函数:不同类中可以有同名成员函数; 命名空间:不同命名空间中可以有同名实体; 模板:模板实例化会生成不同的具体函数 / 类,需区分模板参数。 修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。 调用约定__stdcall(回调调用约定)是Pascal程序的缺省调用方式,通常用于Win32 API中,函数采用从右到左的压栈方式,自己在退出时清空堆栈 12345678910111213void __stdcall funa(...
函数重载
代码仓库shanchuann/CPP-Learninng 函数重载在C语言中,编译时会对函数名添加前缀,如func会变为_func,这也是为什么C语言不支持重载的原因,所以C语言通过函数名直接来对函数进行区分 12void func_i(int a) {}void func_d(double a) {} C++提供函数重载的概念:在C++中可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同或参数类型相同但参数个数不同,称为函数重载 123456789101112131415void func(int a) { cout << "func with int: " << a << endl;}void func(int a, int b) { cout << "func with two int: " << a << ", " << b <...
缺省参数
代码仓库shanchuann/CPP-Learninng 缺省参数核心定义缺省参数是指函数在声明或定义时,为参数指定一个 “默认值”。调用函数时,若未显式传递该参数,编译器会自动使用默认值;若传递了参数,则覆盖默认值。其核心作用是减少函数重载的冗余代码,同时提升调用灵活性(尤其适用于 “可选参数” 场景)。 123456789101112131415161718#include <string>// 函数声明时指定缺省参数(推荐:声明更易被调用者可见)void printMsg(int count = 1, const std::string& msg = "Hello");// 函数定义时不可重复指定默认值(否则编译错误)void printMsg(int count, const std::string& msg) { for (int i = 0; i < count; ++i) { std::cout << msg << std::endl;...
C++引用
代码仓库shanchuann/CPP-Learninng 引用定义:类型& 引用变量名称 = 表变量名称; 1234567891011121314int main() { int a = 10; // a| 10 | int& r = a; // r是a的引用 // r,a| 10 | cout << "a = " << a << ", r = " << r << endl; r = 20; // 修改r的值,实际上是修改a的值 // r,a| 20 | cout << "a = " << a << ", r = " << r << endl; int b = 30; r = b; // 将b的值赋给r,实际上是将b的值赋给a // r,a| 30 | cout ...
标准输入输出流
代码仓库shanchuann/CPP-Learninng 标准输入输出流C++ 标准输入输出流(I/O 流)通过 <iostream> 等头文件封装为面向对象的流对象,是程序与外部设备(键盘、终端、文件)交互的核心机制。相较于 C 语言,C++ 流对象兼具安全性与易用性,支持类型安全的输入输出、灵活的格式控制及动态内存管理。本文聚焦 C++ 标准 I/O 流的核心概念、常用接口及实践示例,帮助开发者快速掌握并正确使用 C++ 标准 I/O 功能。 标准输入流C++ 标准输入以 std::cin 为核心(istream 类的实例),默认与 C 语言 stdin 同步(可混用 C 风格输入),采用 “行缓冲” 机制 —— 仅当输入换行符 \n 时,键盘输入的字符才会同步到 cin 的内存缓冲区。 核心概念 缓冲区与同步:cin 有独立内存缓冲区,默认通过 std::cin.sync_with_stdio(true) 与 stdin 同步;取消同步(设为 false)可提升输入效率,但禁止混用 C 风格输入(如 scanf)。 ...
统一初始化
代码仓库shanchuann/CPP-Learninng 统一初始化传统圆括号初始化可能产生歧义,被编译器误解析为函数声明,而列表初始化可避免这一问题。 1234567class Foo {};// 传统方式的歧义:被解析为“返回Foo的无参函数声明”,而非对象初始化Foo f1(); // 列表初始化:明确为对象初始化(调用默认构造函数)Foo f2{}; 类似地,对于带参数的场景: 12345678910class Bar {public: Bar(int x) {}};// 歧义:被解析为“返回Bar的函数,参数为int类型的x”Bar b1(int x); // 明确为对象初始化(调用Bar(int))Bar b2{10}; 初始化是指为变量赋予初始值在C++中,初始化有多种方式,包括复制初始化和直接初始化。 复制初始化(copy initialization):使用等号=进行初始化 直接初始化(direct initialization):...
lambda表达式(2)
代码存储位置:shanchuann/Modern_CPP + 辅助推导auto* p = +[]{return 6;};这是一个非捕获lambda,可以生成转换函数转换为函数指针,这里的一元+是为了辅助推导,是为了创造合适的语境。自然理解为使用转换函数返回函数指针。此处为int(*)(),即无参、返回int的函数指针, +强制触发这个转换,将lambda直接转为函数指针类型,而非lambda自身的匿名类型。 12int* p = nullptr;+p; +对指针无算术意义,仅将指针(左值)转换为同值的纯右值(prvalue),指针的指向和数值均不改变,属于无副作用的类型转换。因为右边表达式的结果是函数指针类型int(*)(), auto 会自动推导 p 的类型为int(*)(),与 auto*的推导结果完全一致;*仅为显式强调指针类型以提升可读性,并非语法必需。 ODRlambda(隐式或显式)捕获的任何实体均被该lambda表达式ODR使用,所有隐式捕获的变量必须在lambda表达式的可达作用域内声明。即使外部有再多的对象,没有ODR使用就不会被捕获(个别...
lambda表达式(1)
代码存储位置:shanchuann/Modern_CPP lambda 表达式是 C++11 引入的匿名函数,是一个右值表达式,其类型为唯一的未命名非联合非聚合类类型,称为闭包类型(closure type),它被声明在包含 lambda 表达式的最小块作用域、类作用域或命名空间作用域中(用于 ADL)。它可以在需要函数的地方直接定义,无需单独声明,极大简化了代码编写。 123456789//lambda 表达式是 C++11 引入的**匿名函数**,属于*无名的非联合非聚类*类型struct X :decltype([] {}) { // 继承自 lambda 表达式的类型 void operator()() { cout << "X::operator()" << endl; }};int main() { X x; x(); // 调用 X::operator() //输出:X::operator() return 0;} 这是一个有...





