C/C++
文章平均质量分 70
C/C++
flos chen
一般质量较高文章会开放一个月,到下个月中旬会加上VIP要求;
如果有些知识点自己理解很困难,可以私聊我,我梳理后会根据理解情况发大白话文章,互利;
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【C++/Qt 设置 main 函数启动参数的全面指南】
设置 main 函数启动参数指南 本文介绍了多种设置 C++/Qt 程序 main 函数启动参数的方法: IDE 设置:在 Visual Studio/Qt Creator/CLion 的调试配置中直接输入命令行参数 命令行启动:通过终端/命令提示符执行程序时附加参数 代码模拟:可硬编码参数或使用 QCoreApplication::setArguments 动态设置 测试环境:通过 Google Test 等框架注入测试参数 部署脚本:在批处理/shell 脚本中预定义执行参数 环境变量:通过系统环境变量原创 2025-10-24 19:15:00 · 341 阅读 · 0 评论 -
【C++ 为什么引用对象必须被初始化】
本文分析了C++中引用类型与值类型初始化的核心差异。引用作为变量的别名必须初始化且不能为空,而对象作为独立实体可延迟初始化。文章从语义、内存模型和使用安全性三方面解释了这种差异原因,提供了正确初始化的代码示例,并讨论了特殊情况处理方案。最后给出设计建议:优先使用对象、确保引用成员正确初始化、考虑使用指针替代引用,以及利用初始化列表提高效率。这种初始化差异是C++确保类型安全和语义清晰的重要设计。原创 2025-09-13 08:15:00 · 466 阅读 · 0 评论 -
【C++ 为什么常量成员函数可以赋值给引用对象而不能赋值给值对象】
本文解析了常量成员函数中引用类型和值类型成员变量的赋值差异。核心要点包括:1) 常量成员函数承诺不修改非mutable成员;2) 引用类型可以修改指向对象,这不违反const语义;3) 值类型成员在const函数中不能直接修改,除非声明为mutable。文章提供了三种解决方案:使用mutable关键字、移除const限定符或重构设计分离读写操作。理解这些差异有助于正确设计类成员函数,平衡封装性和灵活性需求。原创 2025-09-13 08:00:00 · 467 阅读 · 0 评论 -
【C++ 虚函数表(vtable)的创建时机】
C++虚函数表创建机制解析 虚函数表(vtable)是C++实现多态的核心机制,其生命周期分为三个阶段: 编译期 - 编译器为每个含虚函数的类生成虚表结构,包含虚函数指针和RTTI信息 程序加载期 - 操作系统将虚表写入只读内存段,地址固定不变 对象构造期 - 构造函数隐式初始化vptr指针,构造过程中vptr会随继承层级变化 虚表具有共享性(同类型对象共用)、只读性和高效访问特点。关键注意事项包括:构造函数中避免调用虚函数(此时vptr未完全初始化)、多态基类必须声明虚析构函数、跨动态库边界时需谨慎处理虚原创 2025-08-13 16:51:47 · 831 阅读 · 0 评论 -
【C/C++ const 在成员函数前与后的本质区别:位置决定语义】
const 在成员函数前后的本质区别 在 C++ 中,const 关键字的位置决定了其作用对象和语义: 函数后加 const(常量成员函数) 修饰整个成员函数 承诺不修改对象状态(this指针变为const) 可被const和非const对象调用 支持基于const的函数重载 函数前加 const(常量返回值) 仅修饰返回值 防止返回值被修改 适用于返回指针/引用的情况 不影响函数重载 最佳实践: 不修改对象状态的函数应声明为const成员函数 返回内部数据时优先返回const引用/指针 合理组合使用两种c原创 2025-08-14 07:45:00 · 778 阅读 · 1 评论 -
【C++ 子类的虚函数表有几个?】
摘要:C++中虚函数表是按类创建的。每个定义了虚函数或有虚基类的类都会生成独立的虚函数表,该类的所有对象共享同一个虚表。在单继承中,子类会创建自己的虚函数表(可能继承或覆盖基类虚函数);多重继承时,子类会构建更复杂的虚表结构(可能包含多个部分)。核心结论是:每个子类有且仅有一个属于自己的虚函数表结构,但该结构可能包含多个组成部分以满足多重继承需求。虚函数表是类级别的而非对象级别的概念。原创 2025-08-13 08:15:00 · 906 阅读 · 0 评论 -
【C++ 中使用 double 作为 map 的 key:可行但有风险】
摘要:在C++中可以将double类型作为std::map的键值,但这存在精度风险。虽然语法上合法,但浮点数二进制表示的不精确性会导致相同数值可能被视为不同键。主要问题包括:1) 精度误差导致比较结果不可靠;2) NaN的特殊情况;3) 计算路径不同产生微小差异。解决方案建议:1) 使用带容差的自定义比较器;2) 转换为整数/定点数;3) 采用高精度数学库。最佳实践是尽量避免使用浮点键,可考虑重新设计数据结构或用字符串替代。在必须使用时,定制比较器是最平衡的方案,但需谨慎选择容差值。原创 2025-08-12 10:18:30 · 500 阅读 · 0 评论 -
【C++ 函数后面加 const 的深度解析】
C++中的const成员函数是常量正确性的核心机制,它承诺函数不会修改对象状态(除mutable成员外),并允许const对象调用该方法。编译器会将this指针转为const类型来强制这一约束。const方法与非const方法构成重载,根据对象常量性自动匹配版本。典型应用包括访问器方法、接口设计和STL容器兼容。最佳实践包括最小权限原则、const正确性传播和谨慎使用mutable。该机制纯属编译时检查,不影响性能,却能显著提升代码安全性和可维护性。原创 2025-08-12 10:18:03 · 721 阅读 · 0 评论 -
【C/C++ 构造函数和析构函数可以重载吗?】
C++中构造函数与析构函数的重载规则存在本质差异:构造函数允许重载,通过不同参数列表实现多种初始化方式;而析构函数禁止重载,每个类只能有一个无参数的析构函数。这种差异源于对象创建时的灵活性需求与销毁时的确定性要求。构造函数重载支持委托构造、隐式转换等特性,而析构函数的唯一性确保了资源释放的统一性和继承体系的安全性。最佳实践包括:合理使用explicit构造函数、委托构造,以及为基类声明虚析构函数。理解这些差异是掌握C++对象生命周期管理的关键。原创 2025-07-13 08:15:00 · 1042 阅读 · 0 评论 -
【C++ 构造函数和析构函数可以声明为虚函数吗?】
摘要:C++中构造函数与析构函数的虚函数特性对比鲜明。构造函数不能为虚函数,因虚函数表在构造期间建立;析构函数则必须为虚函数(基类),确保通过基类指针删除派生类对象时正确调用所有析构函数。关键区别在于:构造函数禁止虚函数(类型确定时静态绑定),析构函数推荐虚函数(实现安全销毁)。最佳实践包括:基类必用虚析构、final类可省略、接口类需实现纯虚析构。遵守虚析构规则是防止资源泄漏的核心准则。原创 2025-07-13 08:00:00 · 328 阅读 · 0 评论 -
【MFC/C++ MFC中的消息映射机制】
MFC框架中按钮点击响应通过消息映射机制实现。核心流程包括:1)在头文件声明DECLARE_MESSAGE_MAP宏和消息处理函数;2)在源文件使用BEGIN_MESSAGE_MAP/END_MESSAGE_MAP宏定义映射表,通过ON_BN_CLICKED宏绑定按钮ID与处理函数;3)实现具体的按钮点击处理逻辑。当按钮被点击时,Windows生成WM_COMMAND消息,MFC消息泵路由到父窗口,匹配消息映射表后调用对应处理函数。该机制通过宏实现高效消息分发,避免了虚函数开销,是MFC事件处理的核心设计。原创 2025-07-12 08:15:00 · 636 阅读 · 0 评论 -
【C/C++ 智能指针的空实现】
本文展示了C++中unique_ptr和shared_ptr智能指针的简化实现版本,保留了核心功能但移除了标准库的复杂性。unique_ptr实现了独占所有权和移动语义,shared_ptr实现了引用计数机制。与标准库实现相比,这些空实现缺少了自定义删除器、数组支持、线程安全等高级特性,但足以说明智能指针的基本工作原理。文中还提供了使用示例和输出结果,帮助理解这些智能指针的行为。原创 2025-07-12 08:00:00 · 298 阅读 · 0 评论 -
【C++ 深入解析 C++ 模板中的「依赖类型」】
摘要: 依赖类型是C++模板编程的核心概念,指依赖于模板参数的类型(如迭代器)。编译器需要typename关键字明确指示依赖名称是类型而非值。主要分为嵌套、模板、成员指针和表达式依赖类型。现代C++通过auto、类型别名和概念简化了处理。依赖类型广泛应用于泛型容器、元编程和策略模式中,使用时需注意typename标记和模板参数依赖关系。迭代器是其典型代表,但依赖类型的概念更为广泛,是模板元编程的重要基础。原创 2025-07-11 20:00:00 · 939 阅读 · 0 评论 -
【C/C++ shared_ptr 和 unique_ptr可以互换吗?】
C++智能指针转换指南:std::unique_ptr与std::shared_ptr的区别与转换方法 摘要: 本文对比了C++中两种智能指针的所有权特性:std::unique_ptr(独占所有权)和std::shared_ptr(共享所有权)。关键点包括: 安全转换:unique_ptr可通过移动语义转为shared_ptr 禁止转换:shared_ptr无法直接转为unique_ptr(即使唯一所有者时也存在风险) 核心差异:所有权模型、复制语义、性能开销和循环引用风险 最佳实践:优先使用unique原创 2025-07-11 20:15:00 · 402 阅读 · 0 评论 -
【 C++ 模板中 `template<typename T>` 与 `template<class T>` 的深度解析】
C++模板中typename与class的使用解析 在C++模板编程中,typename和class在声明模板类型参数时功能完全等价,但存在语义差异: 基本用法:两者都可声明模板参数 template // 现代推荐 template // 传统方式 关键区别: typename语义更准确,适用于所有类型 class易让人误解为仅适用于类类型 依赖类型场景必须使用typename 使用建议: 新代码优先使用typename 旧代码维护可保持class 依赖类型必须用typename 两者选择主要取决于代码清原创 2025-06-15 12:50:10 · 1086 阅读 · 0 评论 -
【C/C++ 为什么 unique_ptr 不支持拷贝构造、赋值构造等操作】
std::unique_ptr禁止拷贝构造和拷贝赋值,是为了确保独占所有权语义。其设计核心是单一资源所有权的轻量级管理,通过禁用拷贝避免了多指针共享资源导致的重复释放或悬空指针问题。所有权转移必须通过移动语义(std::move)显式进行,原指针会置空以保证资源唯一归属。这种设计既符合零开销原则,又增强了安全性。相比之下,共享所有权场景应使用std::shared_ptr。简言之,禁用拷贝强制了清晰的资源生命周期管理,是C++资源安全的重要机制。原创 2025-06-13 20:15:00 · 588 阅读 · 0 评论 -
【C++/Qt shared_ptr 与 线程池】合作使用案例
本案例展示了如何在 Qt 线程池中使用 std::shared_ptr 管理多线程任务资源,避免内存泄漏。通过自定义任务类 MyTask 继承 QRunnable,禁用自动删除功能,确保任务对象由 shared_ptr 管理生命周期。主窗口类 MainWindow 使用 QThreadPool 提交任务,并通过信号槽机制实现跨线程通信,确保任务完成后资源自动释放。关键机制包括禁用自动删除、shared_ptr 管理生命周期、跨线程信号槽通信以及 Lambda 捕获 shared_ptr 确保任务执行期间对象原创 2025-05-16 19:15:00 · 525 阅读 · 0 评论 -
【C/C++ Python】python 就这么把 C++ 几千行代码实现的功能给封装到一个接口里面啦!!!
当代开发常见模式是:Python 作为顶层胶水,调用底层 C/C++/Rust 实现的核心模块。既保持了开发效率,又兼顾了执行性能。像 TensorFlow/PyTorch 等框架正是这种架构的典范。如果你是一位 C++ 开发者,最近在接触 python 的话,很可能产生类似的想法~这正是 Python 的哲学魅力所在。最近在学习机器学习,同时产生了一些对于 C++ 和 python 的看法~类似功能用 C++ 需要处理套接字、线程、协议解析等底层细节。原创 2025-03-15 08:15:00 · 558 阅读 · 0 评论 -
【C++/Qt 高精度计算qreal temp = static_cast<qreal>(nwidth) / nImgWidth;】
这行代码是C++中使用Qt框架时的一个类型转换示例。原创 2024-10-27 09:00:00 · 354 阅读 · 0 评论 -
【C/C++ explicit关键字】为什么有了explicit关键字的构造函数 就不能再有 其无参构造函数
关键字的构造函数,你就不能有相同签名的无参构造函数(默认构造函数),除非后者也标记为。,如果它不是必需的。这是因为无参构造函数可能会被用于隐式类型转换,而。试图调用无参的默认构造函数,而这个默认构造函数与。的构造函数,这样它就不会与带参数的构造函数重载。构造函数重载的无参构造函数,除非你也将其标记为。的构造函数,编译器不允许隐式调用无参构造函数。这样可以避免编译器错误,并确保类型的安全使用。在这个例子中,无参构造函数显式地调用了带。在 C++ 中,如果你有一个带有。关键字时,你需要确保不会创建与。原创 2024-10-27 09:00:00 · 492 阅读 · 0 评论 -
【C/C++ Qt shared_ptr | make_shared | QSharedPointer 】绕圈圈
在功能上相似,但它们分别属于不同的库,并且在某些特定场景下可能更适合使用其中一个。在 Qt 应用程序中,通常推荐使用。在较新版本的 Qt 中已经不再推荐使用,而。,因为它可能更好地与 Qt 的其他特性集成。原创 2024-10-26 10:00:00 · 774 阅读 · 0 评论 -
【C/C++ make_shared和shared_ptr直接初始化有什么区别?】
初始化是 C++ 中创建共享智能指针的两种不同方式。它们之间的主要区别在于内存分配、效率、异常安全性和使用上的便利性。的直接初始化,比如当你需要在创建智能指针时立即获取原始指针或者需要与旧代码兼容时。,因为它更高效、更安全,并且在语法上更简洁。然而,有时候你可能需要使用。在实际使用中,推荐使用。原创 2024-10-26 09:00:00 · 580 阅读 · 0 评论 -
【C/C++ STL:vector如何释放空间?】
如果你确实需要释放 vector 分配但未使用的空间,可以尝试使用 swap 技巧或 shrink_to_fit(如果可用并适用)。swap 技巧是强制性的,但可能会引入额外的性能开销(尤其是当 vector 很大时)。shrink_to_fit 是请求性的,其效果可能因编译器和标准库的不同而有所不同。在大多数情况下,让 vector 管理其内存通常是最好的选择,因为这样可以简化代码并可能提高性能。原创 2024-08-09 20:00:00 · 795 阅读 · 0 评论 -
【C/C++ 迭代器++it和it++哪个好,为什么】
在大多数实际情况下,++it和it++之间的性能差异可以忽略不计。选择哪个主要取决于你的具体需求和代码的可读性。如果你不需要保存迭代器递增前的状态,++it可能是一个更清晰、更直接的选择。如果你需要同时访问递增前后的迭代器位置,则可能需要使用it++,但请注意,这可以通过其他方式(如使用两个迭代器)来优化。最后,值得注意的是,随着C++标准库的发展,现代编译器和优化技术通常能够很好地处理这些细微的差异,因此,在大多数情况下,你应该更关注代码的可读性和清晰性,而不是这些微小的性能差异。原创 2024-08-09 20:00:00 · 626 阅读 · 0 评论 -
【C/C++ 多态中的虚函数的虚函数表】详细的了解一下吧(要先知道有虚函数表
多态是面向对象程序设计中的一个重要特性,它允许不同类的对象对同一消息作出响应。在C++中,多态的实现主要依赖于虚函数和虚函数表。以下是对多态中虚函数表的详细描述:虚函数表(Virtual Function Table,简称VTable)是C++中用于支持多态性的一个关键机制。当一个类中包含虚函数时,编译器会为该类生成一个虚函数表,该表包含了指向类中所有虚函数的指针。每个包含虚函数的类的对象都会包含一个指向其所属类的虚函数表的指针(通常称为vptr)。虚函数表的主要作用是支持多态性。通过虚函数表,基类指针或引原创 2024-08-08 20:00:00 · 1378 阅读 · 0 评论 -
【操作系统/C++ malloc 1KB和1MB 有什么区别?brk | mmap】
关于 malloc 如何根据请求的内存大小选择使用 brk 还是 mmap 的机制,是 glibc(GNU C Library)中 malloc 实现的一个常见策略,尽管具体的阈值(如128KB)可能会因 glibc 的不同版本或配置而有所不同。原创 2024-07-27 10:00:00 · 1308 阅读 · 0 评论 -
【C/C++ extern“C”的用法,及C++调用C,C调用的C++案例】
而C语言不支持函数重载,也不进行名字修饰,因此直接使用C++编译器编译的C代码(或C++代码中嵌入的C代码)在链接时可能会因为找不到正确的函数名而导致链接错误。在实际项目中,你会在C++代码中通过extern "C"声明C函数,然后在链接时包含C代码编译生成的目标文件(.o或.obj文件)。为了从C代码中调用cpp_function,你需要在C代码中声明这个函数为extern(尽管这不是必须的,因为extern "C"已经在C++代码中声明了),但重要的是确保链接器能找到C++代码编译生成的函数。原创 2024-07-28 10:00:00 · 517 阅读 · 0 评论 -
【C/C++ final和override关键字】那些比较重要的基础知识
final 关键字用于防止类被继承或成员函数被覆盖,增强设计的封闭性和安全性。override 关键字用于明确表示成员函数是覆盖基类中的虚函数,提高代码的可读性和可维护性,同时编译器会检查覆盖的正确性。原创 2024-07-28 10:00:00 · 260 阅读 · 0 评论 -
【C/C++ 宏定义和typedef的区别及代码示例】越是基础的东西越容易被忽视
定义方式与作用时机使用#define预处理指令进行定义。在预处理阶段(编译之前)进行文本替换,不进行类型检查。宏定义是预处理器指令,不是C/C++的语句,因此末尾不加分号。是C/C++的一个关键字,用于定义新的类型别名。在编译阶段生效,编译器会进行类型检查。typedef定义的是类型别名,因此使用时要加分号表示语句结束。功能与用途主要用于定义常量、简化代码或进行条件编译等。可以进行简单的文本替换,但可能会因为运算符优先级等问题导致意外的结果。原创 2024-07-07 10:00:00 · 784 阅读 · 0 评论 -
【C/C++ 宏定义和函数的区别及代码示例】越是基础常用的东西越容易被忽视
处理时机:宏定义:在预处理阶段处理,即编译器在编译之前将宏定义中的代码直接替换到程序中。这意味着宏定义并不占用程序运行时的内存或执行时间,但它可能会增加编译后的代码大小。函数:在程序运行时被调用和执行。函数执行时需要占用内存(调用栈等)和时间。参数检查:宏定义:不进行类型检查,仅进行文本替换。如果宏的参数在替换后产生了不期望的结果(如运算符优先级问题),可能会导致难以发现的错误。函数:进行严格的类型检查,确保传递给函数的参数类型正确。原创 2024-07-05 20:00:00 · 603 阅读 · 0 评论 -
【C/C++ new/delete和malloc/free的异同及原理】
new是类型安全的,malloc不是。//编译错误//编译无错误new调用名为operator new的标准库函数分配足够空间并调用相关对象的构构造函数,delete对指针所指对象运行适当的析构函数,然后通过调用名为perator delete的标准库函数释放该对象所用内存。后者均没有相关调用。new是封装了malloc,直接free不会报错,但是这只是释放内存,而不会析构对象new和delete是如何实现的?原创 2024-07-04 20:00:00 · 1462 阅读 · 0 评论 -
【COM/ATL 运用ATL工程创建和调用COM组件】
ATL (Active Template Library) 是一个用于简化 COM (Component Object Model) 组件开发的库。使用 ATL,你可以创建 COM 对象,这些对象可以跨进程和跨机器进行通信。下面是一个简单的步骤,说明如何使用 ATL 创建一个简单的 COM 组件,并在另一个程序中使用它。然后在你的 ATL 类中实现这个方法:步骤 3: 注册 COM 组件编译你的 ATL 项目后,你需要注册你的 COM 组件。这通常可以通过运行生成的 DLL 或 EXE 文件的 /R原创 2024-06-15 19:13:01 · 1258 阅读 · 0 评论 -
【C++11 之单例模式线程安全原理+案例】及旧版本互斥锁线程安全案例
在C++11之前,通常我们会使用互斥锁(如pthread_mutex_t在POSIX线程中,或者在C++标准库中使用std::mutex,尽管std::mutex是C++11引入的,但这里我们可以假设我们有一个兼容的互斥锁实现)来保证单例模式的线程安全。请注意,在上面的代码中,我们使用了pthread_mutex_t作为互斥锁,并使用pthread_mutex_lock和pthread_mutex_unlock函数来加锁和解锁。在C++11及之后的版本中,它被广泛用于实现线程安全的单例。原创 2024-06-29 10:00:00 · 1500 阅读 · 0 评论 -
【C++11 之新增容器 array、foward_list、tuple、unordered_(multi)map/set】应知应会
std::array 是一个固定大小的数组容器,它在栈上分配内存,并提供了类似于标准库容器的接口。它提供了更好的类型安全性和范围检查,同时保持了与原生数组相似的性能。std::array 的大小必须在编译时确定,并且不能更改。std::forward_list 是一个单向链表容器,它提供了高效的插入操作(在链表头部插入元素为常数时间)。与 std::list 相比,它只支持前向迭代,不支持双向迭代,因此其空间效率更高。原创 2024-06-23 20:59:25 · 549 阅读 · 1 评论 -
【C++11 之强类型枚举enum class/struct 基本结构及应用场景】了解在enum基础上增加了什么
/ 声明一个名为 Color 的强类型枚举,底层类型为 unsigned intRED, // 枚举值,通常是大写的GREEN,BLUE,// 可以有其他枚举值// 使用枚举类// 使用枚举类的作用域解析运算符 :: 来指定枚举值// ... 其他代码 ...return 0;原创 2024-06-22 12:01:47 · 704 阅读 · 0 评论 -
【C++11 之nullptr关键字 用以消除空指针和0歧义】基础知识必须了解
它的类型是 std::nullptr_t,这是一个新的内置类型,可以隐式转换为任何指针类型,但不能转换为非指针类型(如整数)。因此,使用 nullptr 可以消除上述的歧义。引入 nullptr 的主要目的是解决使用 NULL 或 0 时可能产生的歧义,并提供一个更清晰、更明确的空指针常量表示。此外,nullptr 还与 C++ 的其他语言特性(如模板和类型安全)更好地集成,从而提高了代码的安全性和可靠性。但是,使用 0 作为空指针常量有一个问题:0 既可以表示整数零,也可以表示空指针。原创 2024-06-22 12:00:49 · 430 阅读 · 0 评论 -
【C++11 之auto 自动类型推导】一个你必须知道的基础知识
auto 关键字背后的原理是,编译器会查看变量的初始化表达式,并确定该表达式的类型。然后,编译器将该类型应用于 auto 声明的变量。在上面的代码中,y 被自动推导为 int 类型,因为 x 是 int 类型的。原创 2024-06-21 17:42:37 · 430 阅读 · 0 评论 -
【c++11 之智能指针2 unique、shared、weak *_ptr 原理及案例】及四种智能指针对比分析
熟悉C++11引入的三种智能指针的原理及判断使用场景;理解unique_ptr对auto_ptr的替换;三种指针都是将一些释放操作自动化实现,也可以自己手写智能指针;一张表格分辨四种智能指针:auto_ptr (已废弃)unique_ptrshared_ptrweak_ptr所有权独有(但有问题的拷贝语义)独有共享(引用计数)不拥有(观察)拷贝语义转移所有权(可能导致问题)禁止拷贝,但可以移动引用计数增加不支持赋值语义转移所有权(可能导致问题)原创 2024-06-21 17:41:37 · 2408 阅读 · 0 评论 -
【C++98 智能指针1 auto_ptr的原理及代码案例】已弃用!!
std::auto_ptr 是 C++98 引入的一个简单的独占所有权智能指针,但在 C++11 中已经被弃用(deprecated),并在 C++17 中被移除。这是因为 std::auto_ptr 在所有权转移时的行为(特别是通过赋值和复制操作)可能导致意外的结果和难以调试的问题。原创 2024-06-18 17:45:57 · 354 阅读 · 0 评论 -
【C++17 之 .base() 函数实现正向和反向迭代器之间的交换,原理及代码展示】接上一p
我前期看过一位博主的关于正向迭代器和反向迭代器的图解描述,至今仍印象深刻,稍后我找到了会更新链接,方便大家理解。原创 2024-06-18 17:45:05 · 762 阅读 · 0 评论
分享