函数重载
代码仓库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;} 这是一个有...
Noexcept
代码存储位置:shanchuann/Modern_CPP noexcept 说明符(C++11 起)noexcept 是一个异常说明符(exception specifier),用于明确指定函数是否可能抛出异常。 语法 语法形式 编号 说明 noexcept (1) noexcept(表达式) (2) throw() (3) (C++17 中弃用,C++20 中移除) (1) 等同于 noexcept(true) (2) 若表达式求值为 true,则函数声明为不抛出任何异常。noexcept 后的 ( 始终是此形式的一部分(它绝不能用于开始初始化器)。 (3) 等同于 noexcept(true)(关于其在 C++17 之前的语义,见 “动态异常规范”)。 表达式:可按上下文转换为 bool 类型的常量表达式。 在 C++17 前,noexcept 说明符不属于函数类型(与动态异常规范类似),仅能用于以下场景: 作为 lambda 声明符的一部分; 作为 “顶级函数声明符” 的一部分 —— 用于声明函数、变量、函数类型的非静态数据成员、函数...
CMake从头开始(1)
CMake,Makefile,MakeCMake 是一个 构建系统生成器,它根据一个高级的、跨平台的配置文件 CMakeLists.txt 来生成 Makefile。然后,Make 这个 构建工具读取 Makefile 并执行指令,调用编译器等工具,最终将源代码编译成可执行文件或库。 可以把它们的关系想象成: Make 是工人 Makefile 是给工人的施工图纸 CMake 是 绘制施工图纸的工程师,他可以根据一份更通用的设计稿(CMakeLists.txt)生成适用于不同工地(操作系统 / 编译器)的详细图纸。 Makefile 并不跨平台,CMake 根据编译器类型来决定是否生成 Make file,大多数情况下 CMake 会生成 Makefile;Make 工具(类似批处理工具)是通过调用 makefile 文件中的命令实现编译和链接的。 1. MakeMake 是一个经典的、基于指令的构建工具。它本身并不知道如何编译程序。 它读取一个名为 Makefile 的文件,这个文件里定义了源代码文件之间的依赖关系以及构建规则(如何编译、链接)。Make 根据这些...
用户定义字面量
代码存储位置:shanchuann/Modern_CPP 在 C++ 中,用户定义字面量(User-Defined Literals ,简称 UDL) 是 C++11 引入的特性,允许开发者为特定场景定义自定义的字面量形式。通过 UDL,我们可以为数值、字符串等添加有意义的后缀(如 100m 表示 100 米、30s 表示 30 秒),让代码更直观、可读性更强。 从一个例子开始 类似于定义一个运算符重载 12345678910#include <iostream>using namespace std;void operator""_kg(const char* str, size_t) { cout << str << " 千克" << endl;}int main() { "10.5"_kg; // 调用自定义字面量 //10.5 千克 return 0;} 同样的,我们可以将他的返回值改为 string 类型 ...






