C++凡人修仙法典 - 散修版
序章:荒野独行·代码散修之道
在这数字洪荒的蛮荒时代,C++犹如一部失落于天地间的上古秘典,记载着从代码凡人到编程宗师的艰难蜕变之路。身为散修,你既无家族传承的《语法宝典》,亦无帝国建立的"标准库城池",更难入宗门得窥"STL秘境"的真传。本书以**「荒野修行体系」**为引,将艰深的C++知识化作可攀登的十七重险峰,助你在资源匮乏的野外独自摸索,从拾取语法的残章断简开始,一步步锻造属于自己的神通法器。
散修与编程的荒野生存法则:
- 修炼境界:如荒野散修从吞吐天地灵气(基础语法)开始,在无人指导的险境中摸索前行,历经数据结构的荒原、指针迷宫的试炼,方能如宗门弟子般筑基稳固
- 内功心法:数据类型与运算符是你独自打坐时参悟的**「野性根基」**,没有家族长老为你护法调息,全凭自己在编译错误中领悟真谛
- 神通法术 :函数是你用来自保的**「独门暗器」,类是你亲手打造的 「防护法器」,模板则是你在废墟中偶然拾得的「万象熔炉」**------这些散修神通需在实战中自行摸索组合
- 天劫试炼:内存管理是野外生存的最大凶险,稍有不慎便会坠入"内存泄漏深渊";多线程编程如同驯服荒野异兽,没有宗门长老护持,只能靠自己在崩溃边缘反复试探
本书独创**「散修十七境」**修行体系,自"炼气期·荒野拾遗"至"混沌境·独悟天道",每重境界都是散修在代码荒原中的生死考验:
- 凡阶三境(炼气·筑基·金丹):在无教材可依的困境中摸索基础语法,靠调试器微光辨识数据流向,如荒野猎人般追踪程序执行的蛛丝马迹
- 灵阶六境(元婴·化神·炼虚·合体·大乘·渡劫):在没有师门庇护的险境中参悟面向对象真意,于内存雷区中独自开辟生存空间,每突破一境都如同在代码荒漠中找到绿洲
- 仙阶八境(真仙·天仙·金仙·大罗·准圣·圣人·鸿蒙·混沌):在无人指引的绝境中驾驭多线程风暴,于泛型迷宫中寻找出路,最终在编译器的咆哮声中顿悟语言本源
散修修行,唯靠**「三不」真言**:
- 不依附:无家族资源可依赖,所有基础皆需自己从编译错误中领悟
- 不依靠:无宗门长老可请教,每个bug都需独自面对,每处优化都靠自己摸索
- 不依仗:无标准库城池可退守,必须学会在裸机环境下与原始代码搏斗
愿你在这条孤寂的散修之路上:
- 以**「键盘为剑」**,在错误信息中劈开前路
- 以**「屏幕为镜」**,从报错提示里观照本心
- 以**「编译为炉」**,在反复试炼中锻造真金
当同门宗师依靠家族传承轻松进阶时,你却在荒野中独自参悟;当帝国子弟能调用标准库城池的力量时,你只能手写底层代码;当宗门弟子有长老护法渡劫时,你只能在崩溃边缘独自摸索------但正是这**「无依无靠」的修行,终将使你领悟「真正的代码之道」**!
今日起,你的**「散修C++修行」正式启程------ 在无人问津的代码荒原中独行,在编译器的咆哮声中悟道,终成那「无门无派却独步天下」**的编程散修宗师!
(散修谕:十七重境界,层层皆是生死关。没有捷径可走,没有退路可言,唯有在无数次编译失败与逻辑崩溃中浴火重生,方能在这数字蛮荒中开辟属于自己的编程天地!)
第一卷:凡尘初入
第一章:炼气期 ------C++ 入门基石
境界描述:炼气期是修仙的起点,如同刚接触 C++ 的凡人,需掌握最基础的 "吐纳法门",了解 C++ 的基本语法和数据类型,搭建起编程的根基。
1.1 数据类型与变量 ------ 灵气感知
就像修仙者感知天地间的灵气,C++ 中需要识别不同类型的数据。
cpp
#include <iostream>
using namespace std;
int main() {
// 整数类型,如同固态灵气,不可分割
int age = 18; // 声明一个整数变量age,赋值为18,代表年龄
// 小数类型,如同液态灵气,可自由流动
float height = 1.75f; // 声明一个单精度浮点变量height,赋值为1.75f,代表身高(米)
// 字符类型,如同微小的灵气粒子
char gender = 'M'; // 声明一个字符变量gender,赋值为'M',代表性别(M为男性,F为女性)
// 输出变量值,如同展示自身灵气状况
cout << "年龄:" << age << endl; // 输出年龄
cout << "身高:" << height << "米" << endl; // 输出身高
cout << "性别:" << gender << endl; // 输出性别
return 0;
}
1.2 基本运算符 ------ 灵气运转
运算符就像修仙者运转灵气的法门,能对数据进行各种操作。
cpp
#include <iostream>
using namespace std;
int main() {
int a = 10; // 声明整数变量a并赋值10
int b = 3; // 声明整数变量b并赋值3
// 算术运算符,如同基础的灵气转化
int sum = a + b; // 加法运算,sum为a加b的和
int difference = a - b; // 减法运算,difference为a减b的差
int product = a * b; // 乘法运算,product为a乘b的积
int quotient = a / b; // 除法运算,quotient为a除以b的商(整数除法,只取整数部分)
int remainder = a % b; // 取余运算,remainder为a除以b的余数
cout << "和:" << sum << endl; // 输出和
cout << "差:" << difference << endl; // 输出差
cout << "积:" << product << endl; // 输出积
cout << "商:" << quotient << endl; // 输出商
cout << "余数:" << remainder << endl; // 输出余数
return 0;
}
第二章:筑基期 ------ 流程控制与函数初现
境界描述:筑基期是修仙的关键阶段,需稳固根基。在 C++ 中,对应掌握流程控制语句和函数的基本使用,让代码按照一定的逻辑有序执行,如同搭建稳固的修仙洞府。
2.1 条件语句 ------ 岔路抉择
条件语句如同修仙者在岔路口选择不同的道路,根据条件执行不同的代码块。
cpp
#include <iostream>
using namespace std;
int main() {
int score = 85; // 声明考试分数变量并赋值85
// if语句,如同根据外界情况选择行动
if (score >= 90) { // 如果分数大于等于90
cout << "优秀" << endl; // 输出优秀
} else if (score >= 60) { // 否则如果分数大于等于60
cout << "及格" << endl; // 输出及格
} else { // 否则(分数小于60)
cout << "不及格" << endl; // 输出不及格
}
return 0;
}
2.2 循环语句 ------ 往复修炼
循环语句如同修仙者日复一日的修炼,重复执行某段代码。
cpp
#include <iostream>
using namespace std;
int main() {
// for循环,如同设定好修炼次数的闭关
for (int i = 1; i <= 5; i++) { // 从1开始,每次加1,直到i大于5结束
cout << "第" << i << "次修炼" << endl; // 输出修炼次数
}
// while循环,如同只要条件满足就持续修炼
int j = 1; // 初始化计数器
while (j <= 3) { // 当j小于等于3时
cout << "第" << j << "次巩固" << endl; // 输出巩固次数
j++; // 计数器加1
}
return 0;
}
2.3 函数基础 ------ 神通初显
函数如同修仙者掌握的基础神通,将一段代码封装起来,方便重复调用。
cpp
#include <iostream>
using namespace std;
// 定义一个加法函数,如同创造一个加法神通
int add(int num1, int num2) { // 函数名add,接收两个整数参数num1和num2
int result = num1 + num2; // 计算两数之和
return result; // 返回计算结果
}
int main() {
int a = 5, b = 3; // 声明两个整数变量
int sum = add(a, b); // 调用add函数,传入a和b,接收返回结果
cout << a << " + " << b << " = " << sum << endl; // 输出结果
return 0;
}
第二卷:道途精进
第三章:金丹期 ------ 数组与字符串
境界描述:金丹期修士凝结金丹,实力大增。在 C++ 中,对应掌握数组和字符串,能高效处理一系列相关数据,如同金丹中蕴含的庞大能量。
3.1 数组 ------ 灵气阵列
数组如同整齐排列的灵气阵列,能存储多个相同类型的数据。
cpp
#include <iostream>
using namespace std;
int main() {
// 声明一个整型数组,如同创建一个存放灵气的容器
int nums[5] = {1, 2, 3, 4, 5}; // 数组nums有5个元素,分别为1、2、3、4、5
// 遍历数组,如同查看阵列中的每一份灵气
for (int i = 0; i < 5; i++) { // i从0到4,依次访问数组元素
cout << nums[i] << " "; // 输出数组元素
}
cout << endl;
return 0;
}
3.2 字符串 ------ 字符之链
字符串如同由字符串联而成的链条,用于处理文本信息。
cpp
#include <iostream>
#include <string> // 引入字符串头文件
using namespace std;
int main() {
// 声明一个字符串,如同创建一条字符项链
string name = "修仙者"; // 字符串name为"修仙者"
// 字符串操作,如同对项链进行修饰
name += "张三"; // 字符串拼接,name变为"修仙者张三"
cout << "姓名:" << name << endl; // 输出姓名
cout << "长度:" << name.length() << endl; // 输出字符串长度
return 0;
}
第四章:元婴期 ------ 指针与引用
境界描述:元婴期修士孕育出元神,可离体行事。在 C++ 中,指针和引用就像元神,能间接操作内存中的数据,灵活且强大。
4.1 指针 ------ 元神出窍
指针如同元神离体,指向内存中的数据,可以通过指针访问和修改数据。
cpp
#include <iostream>
using namespace std;
int main() {
int num = 10; // 声明一个整数变量num
int* p = # // 声明一个整型指针p,指向num的地址(&为取地址符)
cout << "num的值:" << num << endl; // 输出num的值
cout << "p指向的值:" << *p << endl; // *为解引用符,输出p指向的值
*p = 20; // 通过指针修改num的值
cout << "修改后num的值:" << num << endl; // 输出修改后的num值
return 0;
}
4.2 引用 ------ 元神分身
引用如同元神的分身,是变量的别名,与变量共享同一块内存。
cpp
#include <iostream>
using namespace std;
int main() {
int a = 5; // 声明整数变量a
int& b = a; // 声明引用b,作为a的别名
cout << "a的值:" << a << endl; // 输出a的值
cout << "b的值:" << b << endl; // 输出b的值(与a相同)
b = 10; // 通过引用修改a的值
cout << "修改后a的值:" << a << endl; // 输出修改后的a值
return 0;
}
第五章:化神期 ------ 类与对象基础
境界描述:化神期修士可神游太虚,掌控之力大增。在 C++ 中,类与对象是面向对象编程的基础,如同创建一个个具有特定属性和行为的修仙者。
5.1 类的定义与对象创建 ------ 塑造生灵
类如同生灵的蓝图,定义了属性和行为;对象则是根据蓝图创建的具体生灵。
cpp
#include <iostream>
using namespace std;
// 定义一个"修士"类,如同制定修士的模板
class Cultivator {
public: // 公共成员,外部可访问
string name; // 姓名属性
int level; // 等级属性
// 修炼方法,如同修士的行为
void practice() {
level++; // 等级提升
cout << name << "修炼后等级提升至" << level << endl; // 输出修炼结果
}
};
int main() {
// 创建一个修士对象,如同根据模板塑造一个修士
Cultivator c1;
c1.name = "张三"; // 给对象的属性赋值
c1.level = 1;
c1.practice(); // 调用对象的方法
return 0;
}
5.2 构造函数与析构函数 ------ 生灭之道
构造函数如同生灵诞生时的初始化,析构函数如同生灵消亡时的清理。
cpp
#include <iostream>
using namespace std;
class Treasure {
public:
string name; // 宝物名称
// 构造函数,对象创建时自动调用
Treasure(string n) {
name = n;
cout << name << "被创造出来了" << endl; // 输出宝物创建信息
}
// 析构函数,对象销毁时自动调用
~Treasure() {
cout << name << "被销毁了" << endl; // 输出宝物销毁信息
}
};
int main() {
Treasure t1("宝剑"); // 创建对象,调用构造函数
{
Treasure t2("丹药"); // 作用域内创建对象
} // 作用域结束,t2销毁,调用析构函数
return 0; // 程序结束,t1销毁,调用析构函数
}
第三卷:大道争锋
第六章:炼虚期 ------ 继承与多态
境界描述:炼虚期修士可虚化实体,变幻莫测。在 C++ 中,继承与多态让类之间产生关联和变化,如同不同辈分和流派的修仙者各有传承又各具特色。
6.1 继承 ------ 血脉传承
继承如同修仙者的血脉传承,子类可以继承父类的属性和方法,并可以添加新的内容。
cpp
#include <iostream>
using namespace std;
// 父类:修士
class Cultivator {
public:
string name;
int level;
void practice() {
level++;
cout << name << "修炼,等级提升" << endl;
}
};
// 子类:剑修,继承自修士
class SwordCultivator : public Cultivator {
public:
// 剑修特有技能
void swingSword() {
cout << name << "挥剑攻击" << endl; // 可以使用父类的属性
}
};
int main() {
SwordCultivator sc;
sc.name = "李四";
sc.level = 2;
sc.practice(); // 继承父类的方法
sc.swingSword(); // 子类特有方法
return 0;
}
6.2 多态 ------ 变幻之术
多态如同修仙者的变幻之术,同一操作作用于不同对象,可产生不同的结果。
cpp
#include <iostream>
using namespace std;
// 父类:灵根
class SpiritRoot {
public:
// 虚函数,允许子类重写
virtual void show() {
cout << "普通灵根" << endl;
}
};
// 子类:金灵根
class GoldSpiritRoot : public SpiritRoot {
public:
// 重写父类方法
void show() override {
cout << "金灵根" << endl;
}
};
// 子类:木灵根
class WoodSpiritRoot : public SpiritRoot {
public:
void show() override {
cout << "木灵根" << endl;
}
};
// 展示灵根的函数,接收父类指针
void display(SpiritRoot* root) {
root->show(); // 调用的是子类重写后的方法
}
int main() {
SpiritRoot* g = new GoldSpiritRoot();
SpiritRoot* w = new WoodSpiritRoot();
display(g); // 输出金灵根
display(w); // 输出木灵根
delete g;
delete w;
return 0;
}
第七章:合体期 ------STL 容器基础
境界描述:合体期修士身心合一,力量凝聚。STL 容器如同各种储物法宝,能高效存储和管理数据,让数据操作更加便捷。
7.1 vector 容器 ------ 可扩容的乾坤袋
vector 如同可自动扩容的乾坤袋,能动态存储多个元素。
cpp
#include <iostream>
#include <vector> // 引入vector头文件
using namespace std;
int main() {
// 创建一个vector容器,如同制作一个乾坤袋
vector<int> bag;
// 向容器中添加元素,如同往乾坤袋中放东西
bag.push_back(10); // 添加10
bag.push_back(20); // 添加20
bag.push_back(30); // 添加30
// 遍历容器,如同查看乾坤袋中的物品
for (int i = 0; i < bag.size(); i++) { // size()返回元素个数
cout << bag[i] << " "; // 访问元素
}
cout << endl;
return 0;
}
7.2 map 容器 ------ 带标签的储物格
map 如同带有标签的储物格,每个元素都有一个键和对应的值。
cpp
#include <iostream>
#include <map> // 引入map头文件
using namespace std;
int main() {
// 创建一个map容器,如同制作带标签的储物格
map<string, int> storage;
// 向map中添加元素(键值对),如同在储物格贴标签放东西
storage["灵石"] = 100; // 键为"灵石",值为100
storage["丹药"] = 5; // 键为"丹药",值为5
// 遍历map,如同查看每个储物格
for (auto it = storage.begin(); it != storage.end(); it++) { // it为迭代器
cout << it->first << ":" << it->second << endl; // first为键,second为值
}
return 0;
}
第八章:大乘期 ------ 模板基础
境界描述:大乘期修士距离飞升仅一步之遥,神通广大。模板如同万能的模具,能创建适用于多种数据类型的函数和类,极大提高代码的复用性。
8.1 函数模板 ------ 万能神通
函数模板如同能适应多种情况的万能神通,可对不同类型的数据进行相同操作。
cpp
#include <iostream>
using namespace std;
// 定义函数模板,如同创造万能神通的法门
template <typename T> // T为类型参数,可代表各种数据类型
T add(T a, T b) { // 函数可接收T类型的参数a和b
return a + b; // 返回a加b的结果,适用于多种类型
}
int main() {
// 对整数使用add函数
int num1 = 5, num2 = 3;
cout << "整数相加:" << add(num1, num2) << endl; // 输出8
// 对小数使用add函数
double d1 = 2.5, d2 = 1.3;
cout << "小数相加:" << add(d1, d2) << endl; // 输出3.8
return 0;
}
8.2 类模板------万能宝具
类模板如同能变化多种形态的万能宝具,可创建适用于不同数据类型的类。
cpp
#include <iostream>
using namespace std;
// 定义类模板,如同打造万能宝具的模板
template <typename T>
class Storage {
private:
T item; // 存储T类型的物品
public:
// 构造函数,初始化存储的物品
Storage(T i) : item(i) {}
// 获取存储的物品
T get_item() {
return item;
}
// 修改存储的物品
void set_item(T new_item) {
item = new_item;
}
};
int main() {
// 创建存储整数的Storage对象
Storage<int> int_storage(10);
cout << "存储的整数:" << int_storage.get_item() << endl; // 输出10
// 创建存储字符串的Storage对象
Storage<string> str_storage("修仙秘籍");
cout << "存储的字符串:" << str_storage.get_item() << endl; // 输出修仙秘籍
return 0;
}
第四卷:飞升之路
第九章:渡劫期------内存管理深化
境界描述:渡劫期修士需经历雷劫考验,稳固道基。在C++中,对应深入理解内存管理,避免内存泄漏等问题,如同安全渡过雷劫。
9.1 动态内存分配与释放------灵气调控
动态内存分配如同根据需求召唤灵气,使用完后需及时释放,避免灵气紊乱。
cpp
#include <iostream>
using namespace std;
int main() {
// 动态分配单个整数的内存,如同召唤一股灵气
int* p = new int(5); // 分配内存并初始化值为5
cout << "动态分配的整数:" << *p << endl; // 输出5
// 动态分配数组的内存,如同召唤一阵灵气
int* arr = new int[3]{1, 2, 3}; // 分配3个整数的内存并初始化
cout << "动态分配的数组:";
for (int i = 0; i < 3; i++) {
cout << arr[i] << " "; // 输出1 2 3
}
cout << endl;
// 释放动态分配的内存,如同散去灵气
delete p; // 释放单个整数的内存
delete[] arr; // 释放数组的内存
return 0;
}
9.2 智能指针------自动护道
智能指针如同自动护道的灵兽,能自动管理动态内存,避免内存泄漏。
cpp
#include <iostream>
#include <memory> // 引入智能指针头文件
using namespace std;
int main() {
// unique_ptr:独占所有权的智能指针
unique_ptr<int> u_ptr(new int(10)); // 管理一个整数的内存
cout << "unique_ptr管理的值:" << *u_ptr << endl; // 输出10
// shared_ptr:共享所有权的智能指针
shared_ptr<int> s_ptr1(new int(20));
shared_ptr<int> s_ptr2 = s_ptr1; // 共享所有权
cout << "shared_ptr管理的值:" << *s_ptr1 << endl; // 输出20
cout << "引用计数:" << s_ptr1.use_count() << endl; // 输出2(两个指针共享)
return 0; // 智能指针自动释放内存,无需手动操作
}
第十章:真仙期 ------ 异常处理
境界描述:天仙期修士神通广大,能应对各种突发状况。异常处理如同修仙者的护身法术,能在程序出错时进行处理,避免程序崩溃。
10.1 异常抛出与捕获 ------ 危机应对
异常抛出如同遇到危机发出信号,异常捕获如同收到信号后采取应对措施。
cpp
#include <iostream>
using namespace std;
// 可能抛出异常的函数
int divide(int a, int b) {
if (b == 0) {
// 抛出异常,如同发出危机信号
throw "除数不能为0"; // 抛出字符串类型的异常
}
return a / b;
}
int main() {
int num1 = 10, num2 = 0;
try { // 尝试执行可能抛出异常的代码
int result = divide(num1, num2);
cout << "结果:" << result << endl;
} catch (const char* msg) { // 捕获异常,如同应对危机
cout << "出错了:" << msg << endl; // 输出出错了:除数不能为0
}
return 0;
}
10.2 异常安全 ------ 稳固道心
异常安全如同修仙者稳固道心,确保在异常发生时,程序状态依然可控,资源不被泄露。
cpp
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
// 异常安全的函数
void safe_operation(vector<int>& vec) {
// 使用智能指针管理资源,确保异常时资源释放
unique_ptr<int> ptr(new int(5));
try {
vec.push_back(10);
// 模拟异常
throw runtime_error("模拟错误");
vec.push_back(20); // 此句不会执行
} catch (const exception& e) {
cout << "捕获异常:" << e.what() << endl; // 输出捕获异常:模拟错误
}
// 智能指针自动释放内存,vector虽只添加了10,但状态正常
}
int main() {
vector<int> my_vec;
safe_operation(my_vec);
cout << "vector中的元素:";
for (int num : my_vec) {
cout << num << " "; // 输出10
}
cout << endl;
return 0;
}
第十一章:天仙期------STL算法与迭代器
境界描述:真仙期修士超脱凡尘,神通更胜。STL算法与迭代器如同仙家法术,能高效处理容器中的数据。
11.1 迭代器------遍历法宝
迭代器如同遍历容器的法宝,能便捷地访问容器中的元素。
cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {1, 2, 3, 4, 5}; // 创建vector容器
// 获取迭代器,如同拿到遍历法宝
vector<int>::iterator it = nums.begin(); // begin()指向第一个元素
// 使用迭代器遍历容器
cout << "vector中的元素:";
while (it != nums.end()) { // end()指向最后一个元素的下一个位置
cout << *it << " "; // *it获取当前元素
it++; // 迭代器移动到下一个元素
}
cout << endl;
return 0;
}
11.2 STL算法------仙家妙法
STL算法如同仙家妙法,能对容器中的元素进行各种操作,如排序、查找等。
cpp
#include <iostream>
#include <vector>
#include <algorithm> // 引入STL算法头文件
using namespace std;
int main() {
vector<int> nums = {3, 1, 4, 1, 5}; // 创建vector容器
// 排序算法,如同整理法宝
sort(nums.begin(), nums.end()); // 对容器中的元素进行排序
cout << "排序后的元素:";
for (int num : nums) {
cout << num << " "; // 输出1 1 3 4 5
}
cout << endl;
// 查找算法,如同寻找宝物
int target = 3;
auto it = find(nums.begin(), nums.end(), target); // 查找target
if (it != nums.end()) {
cout << "找到" << target << ",位置在第" << it - nums.begin() + 1 << "个" << endl; // 输出找到3,位置在第3个
} else {
cout << "未找到" << target << endl;
}
return 0;
}
第十二章:金仙期 ------ 多线程基础
境界描述:金仙期修士可分身多处,同时处理事务。多线程如同修士的分身术,能让程序同时执行多个任务,提高效率。
12.1 线程创建与启动 ------ 分身术
线程创建与启动如同施展分身术,创建多个执行流同时工作。
cpp
#include <iostream>
#include <thread> // 引入线程头文件
using namespace std;
// 线程执行的函数
void task1() {
for (int i = 0; i < 5; i++) {
cout << "任务1执行中:" << i << endl;
}
}
void task2() {
for (int i = 0; i < 5; i++) {
cout << "任务2执行中:" << i << endl;
}
}
int main() {
// 创建线程,如同分出分身
thread t1(task1); // 线程t1执行task1
thread t2(task2); // 线程t2执行task2
// 等待线程完成,如同等待分身回归
t1.join();
t2.join();
cout << "所有任务完成" << endl;
return 0;
}
12.2 互斥锁 ------ 资源守护
互斥锁如同守护资源的结界,防止多个线程同时访问共享资源导致混乱。
cpp
#include <iostream>
#include <thread>
#include <mutex> // 引入互斥锁头文件
using namespace std;
int shared_num = 0; // 共享资源
mutex mtx; // 互斥锁
// 线程函数,修改共享资源
void increment() {
for (int i = 0; i < 10000; i++) {
// 加锁,如同开启结界
lock_guard<mutex> lock(mtx); // 自动解锁,确保异常时也能释放
shared_num++; // 修改共享资源
// 自动解锁
}
}
int main() {
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << "共享变量最终值:" << shared_num << endl; // 输出20000
return 0;
}
第十三章:大罗金仙期 ------lambda 表达式与函数对象
境界描述:大罗金仙期修士法术圆融,可随意组合创造新法术。lambda 表达式与函数对象如同灵活的法术组合,能简化代码,增强功能。
13.1 lambda 表达式 ------ 瞬时法术
lambda 表达式如同临时施展的瞬时法术,可在需要时快速定义匿名函数。
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> nums = {3, 1, 4, 2};
// 使用lambda表达式作为排序规则
sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b; // 降序排序
});
cout << "降序排序后:";
for (int num : nums) {
cout << num << " "; // 输出4 3 2 1
}
cout << endl;
// 使用lambda表达式捕获外部变量
int threshold = 2;
auto is_greater = [threshold](int num) {
return num > threshold; // 判断是否大于threshold
};
cout << "大于" << threshold << "的数:";
for (int num : nums) {
if (is_greater(num)) {
cout << num << " "; // 输出4 3
}
}
cout << endl;
return 0;
}
13.2 函数对象 ------ 固化法术
函数对象如同固化的法术,将函数封装成对象,可携带状态,更灵活地使用。
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 函数对象,如同固化的法术
class Multiplier {
private:
int factor; // 携带的状态:乘数
public:
Multiplier(int f) : factor(f) {}
// 重载()运算符,使对象可像函数一样调用
int operator()(int num) const {
return num * factor; // 执行乘法操作
}
};
int main() {
vector<int> nums = {1, 2, 3, 4};
vector<int> result(nums.size());
// 使用函数对象进行转换
Multiplier times2(2); // 乘数为2的函数对象
transform(nums.begin(), nums.end(), result.begin(), times2);
cout << "乘以2后的结果:";
for (int num : result) {
cout << num << " "; // 输出2 4 6 8
}
cout << endl;
return 0;
}
第十四章:准圣期 ------ 模板元编程入门
境界描述:准圣期修士触及法则本源,可在编译期推演变化。模板元编程如同在编译期进行法术推演,将计算提前,提高程序运行效率。
14.1 编译期计算 ------ 法则推演
模板元编程可在编译期进行计算,如同修士在闭关时推演法术,提前得出结果。
cpp
#include <iostream>
using namespace std;
// 模板元函数,计算n的阶乘(编译期计算)
template <int n>
struct Factorial {
static const int value = n * Factorial<n - 1>::value; // 递归计算
};
// 模板特化,终止条件(0的阶乘为1)
template <>
struct Factorial<0> {
static const int value = 1;
};
int main() {
// 编译期已计算出结果
cout << "5的阶乘:" << Factorial<5>::value << endl; // 输出120
cout << "10的阶乘:" << Factorial<10>::value << endl; // 输出3628800
return 0;
}
14.2 类型判断 ------ 属性洞察
模板元编程可在编译期判断类型属性,如同修士洞察万物属性,精准把握事物本质。
cpp
#include <iostream>
using namespace std;
// 模板元函数,判断是否为指针类型
template <typename T>
struct IsPointer {
static const bool value = false; // 默认不是指针
};
// 模板特化,针对指针类型
template <typename T>
struct IsPointer<T*> {
static const bool value = true; // 是指针
};
int main() {
cout << "int是否为指针:" << IsPointer<int>::value << endl; // 输出0
cout << "int*是否为指针:" << IsPointer<int*>::value << endl; // 输出1
cout << "string*是否为指针:" << IsPointer<string*>::value << endl; // 输出1
return 0;
}
第十五章:圣人期 ------ 内存模型与缓存优化
境界描述:圣人期修士掌控空间法则,对内存布局了如指掌。内存模型与缓存优化如同修士优化自身灵气运转,让数据访问更高效。
15.1 内存对齐 ------ 空间规整
内存对齐如同修士规整自身空间,让数据在内存中按一定规则排列,提高访问效率。
cpp
#include <iostream>
using namespace std;
// 未优化对齐的结构体
struct UnalignedStruct {
char a; // 1字节
int b; // 4字节
char c; // 1字节
}; // 实际占用12字节(因内存对齐)
// 优化对齐的结构体
struct AlignedStruct {
int b; // 4字节
char a; // 1字节
char c; // 1字节
}; // 实际占用8字节(更紧凑)
int main() {
cout << "未优化结构体大小:" << sizeof(UnalignedStruct) << endl; // 输出12
cout << "优化后结构体大小:" << sizeof(AlignedStruct) << endl; // 输出8
// 内存对齐规则:每个成员起始地址是自身大小的整数倍
// 如同物品摆放需符合架子间距,提升存取效率
return 0;
}
15.2 缓存优化 ------ 灵气聚散
缓存优化如同修士聚集灵气,让数据访问符合 CPU 缓存机制,提升程序运行速度。
cpp
#include <iostream>
#include <vector>
#include <chrono>
using namespace std;
// 缓存不友好的访问(跳跃式)
long long bad_cache(const vector<int>& v) {
auto start = chrono::high_resolution_clock::now();
long long sum = 0;
for (size_t i = 0; i < v.size(); i += 100) { // 步长过大,缓存利用率低
sum += v[i];
}
auto end = chrono::high_resolution_clock::now();
cout << "缓存不友好耗时:"
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
<< "μs" << endl;
return sum;
}
// 缓存友好的访问(连续式)
long long good_cache(const vector<int>& v) {
auto start = chrono::high_resolution_clock::now();
long long sum = 0;
for (int num : v) { // 连续访问,充分利用缓存
sum += num;
}
auto end = chrono::high_resolution_clock::now();
cout << "缓存友好耗时:"
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
<< "μs" << endl; // 通常比缓存不友好版本快5-10倍
return sum;
}
int main() {
vector<int> v(10000000, 1); // 1000万个元素
bad_cache(v);
good_cache(v);
return 0;
}
第十六章:鸿蒙期 ------ 编译原理与链接
境界描述:鸿蒙期修士见证天地初开,通晓代码从文本到执行的全过程。编译与链接如同天地演化,将源代码转化为可执行程序。
16.1 编译流程 ------ 开天辟地
编译流程如同鸿蒙演化,将源代码逐步转化为机器码。 // 示例代码:hello.cpp
cpp
#include <iostream>
using namespace std;
int main() {
cout << "Hello, 鸿蒙!" << endl;
return 0;
}
/* 编译流程解析(命令行操作):
-
预处理(展开宏、头文件): g++ -E hello.cpp -o hello.i 生成预处理后的代码(包含所有头文件内容)
-
编译(生成汇编代码): g++ -S hello.i -o hello.s 将C++代码转化为汇编指令
-
汇编(生成目标文件): g++ -c hello.s -o hello.o 将汇编指令转化为机器码(二进制)
-
链接(生成可执行文件): g++ hello.o -o hello 链接所需库文件(如cout对应的标准库),生成最终程序 */
16.2 符号解析与重定位 ------ 万物归位 符号解析与重定位如同鸿蒙中的万物归位,确保程序中函数和变量的引用正确关联。 // file1.cpp(定义符号)
cpp
#include <iostream>
using namespace std;
int global_var = 42; // 全局变量符号
int add(int a, int b) { // 函数符号
return a + b;
}
// file2.cpp(引用符号)
cpp
#include <iostream>
using namespace std;
extern int global_var; // 声明外部符号
extern int add(int, int); // 声明外部函数
int main() {
cout << "全局变量:" << global_var << endl;
cout << "3+5=" << add(3, 5) << endl;
return 0;
}
/* 链接过程解析:
- 编译后生成file1.o和file2.o,各自包含符号表
- 链接器将file2.o中引用的global_var和add与file1.o中的定义关联
- 重定位:调整变量和函数的地址,确保内存中位置正确 最终生成可执行程序,符号引用全部生效 */
第十七章:混沌境 ------C++20 及未来特性
境界描述:混沌境修士超越法则束缚,洞察语言发展的未来。C++20 及后续特性如同混沌初开的新秩序,引领编程范式革新。
17.1 概念(Concepts)------ 法则约束
概念如同混沌中的法则约束,精确限制模板参数的类型,使错误信息更清晰。
cpp
#include <iostream>
#include <type_traits>
using namespace std;
// 定义概念:整数类型
template <typename T>
concept Integral = is_integral_v<T>;
// 定义概念:可打印类型
template <typename T>
concept Printable = requires(T a) {
{ cout << a } -> same_as<decltype(cout)>;
};
// 仅接受整数类型
template <Integral T>
T multiply(T a, T b) {
return a * b;
}
// 仅接受可打印类型
template <Printable T>
void print(T x) {
cout << "打印:" << x << endl;
}
int main() {
multiply(3, 5); // 正确(int是整数)
// multiply(2.5, 3.6); // 错误(double不满足Integral)
print("混沌境"); // 正确(字符串可打印)
print(123); // 正确(整数可打印)
return 0;
}
17.2 协程(Coroutines)------ 时空折叠
协程如同混沌中的时空折叠,允许函数暂停和恢复,高效处理异步操作。
cpp
#include <iostream>
#include <coroutine>
#include <chrono>
#include <thread>
using namespace std;
// 协程返回类型
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
suspend_never initial_suspend() { return {}; } // 立即执行
suspend_never final</doubaocanvas>
_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
// 自定义暂停器
struct Delay {
chrono::milliseconds ms;
bool await_ready () const { return ms.count () == 0; }
void await_suspend (coroutine_handle<> h) {
thread (h, ms = ms { // 启动线程等待
this_thread::sleep_for (ms);
h.resume (); // 恢复协程
}).detach ();
}
void await_resume () {}
};
// 协程函数
Task async_task () {
cout << "任务开始" << endl;
co_await Delay {500ms}; // 暂停 500ms
cout << "500ms 后恢复" << endl;
co_await Delay {1000ms}; // 再暂停 1000ms
cout << "任务完成" << endl;
}
int main () {
async_task ();
this_thread::sleep_for (2000ms); // 等待协程完成
return 0;
}
17.3 范围库(Ranges)------混沌梳理
范围库如同梳理混沌的工具,简化容器操作,使代码更简洁流畅。
cpp
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;
int main() {
vector<int> nums = {3, 1, 4, 1, 5, 9, 2};
// 范围管道:过滤偶数→乘以2→排序→输出
auto result = nums | ranges::views::filter([](int n) { return n % 2 == 0; })
| ranges::views::transform([](int n) { return n * 2; })
| ranges::views::sort;
cout << "处理结果:";
for (int n : result) {
cout << n << " "; // 输出4 8 12(2→4,4→8,6→12)
}
cout << endl;
return 0;
}
终章:大道归一
从炼气期的基础语法到混沌境的前沿特性,《C++ 凡人修仙传》完整呈现了 C++ 世界的修炼之路。每个境界对应着不同层次的知识,从简单的变量操作到复杂的模板元编程,从单线程执行到多线程协同,再到未来语言特性的展望。 编程之路如同修仙,没有捷径可走,唯有不断实践、感悟,才能从凡人逐步晋升为编程大神。当你能将各境界的知识融会贯通,灵活运用在实际项目中时,便真正达到了 "大道归一" 的境界,为开启全民编程时代贡献自己的力量。 愿每一位读者都能在 C++ 的修仙之路上不断精进,终成正果!