2026 - 零碎知识随记录

零碎语言知识:

零碎语言知识

  1. map中,通过 for(auto &[key, value] : map) 中取出来的key的值默认是const类型的
  2. .h会定义多次变量,而.cc只会定义一次,每个引用#include ".h" 的地方都会定义一次变量。
cpp 复制代码
// a.h -> gflag 声明
DECLARE_uint32(global_val);
// a.cc -> gflag 定义
DEFINE_uint32(global_val, 5000, "uint val of global");
// 任一使用.cc
#include "a.h"
const auto global_val = FLAGS_global_val;
处理 global_val;
  1. 最容易出现问题指针存储方式:容器存储对象,map结构存储<key, 对象指针>,当容器变动(map的rehash,vector的扩容),导致对象重新分配内存存储,这样map结构中的对象指针将失效,从而引发coredump等严重问题
cpp 复制代码
class A {public: string name; int val;};
vector<A> aVec;
aVec.emplace(A("a", 1));
map<string, A*> name2Val;
name2Val["a"] = &aVec[0];
// 若后续不断emplace_back元素,导致aVec扩容,此时 &aVec[0] 与 彼时的 &aVec[0] 已经不同
name2Val["a"];  // -> 导致coredump

// 推荐做法:
vector<unique_ptr<A>> aUVec;
aVec.emplace(make_unique<A>("a", 1));
name2Val["a"] = aVec[0].get();
// 后续即使emplace_back元素,导致aVec扩容,也只是unique_ptr的地址发生变化,而不是对象的地址发生变化
name2Val["a"];  // bingo

给一个对比图

  1. 访问DCS时,若是热KEY,可能会击穿DCS缓存。 1. 本地拥有LRU能力。(不治本) 2. 当前一键屏蔽,返回一个失败的值。
  2. static变量一定需要在类外定义一次
  3. unordered_set插入A类型对象,需要为A定义哈希函数和等号运算符,或者使用unique_ptr包裹后使用。
  4. 下面代码共进行了多少次拷贝?
cpp 复制代码
string GetName() {
	string name = "xxx"; 
	return name;
}
auto x = GetName();
// 7.1 没有开启返回值优化,xxx会先拷贝到返回值临时对象,再从临时对象拷贝到x,共2次拷贝,拷贝的方式会根据c++版本的不同而不同。
// 7.2 开启返回值优化,xxx会直接拷贝到x处。
  1. 不能move对象
cpp 复制代码
真正不能move的对象主要包括:
基本类型(移动=拷贝,无意义但可行)
包含const成员、引用、不可移动成员的对象
明确删除移动操作的类型
某些标准库类型(std::mutex, std::atomic, std::array等)
union包含非平凡类型(需要特殊处理)

在C++中,"不能move"通常意味着:
编译错误(移动操作被删除)
移动退化为拷贝(性能无提升)
运行时未定义行为(如果强制转换并移动)
  1. memset 破坏虚函数指针, (因为虚函数指针指向了虚函数表) memcmp 填充数据无法正确比较
  2. const _cast 转化,只用来适配接口,且接口必须不修改原值(属于接口设计问题)
  3. static_assert()用于做编译期间的断言,编译时报错
  4. switch case [[fallthrough]] 表明显示下沉处理
  5. 资源访问校验:当外部数据参与数组索引,内存申请大小,内存复制长度,指针偏移等操作时,必须对数据的大小进行严格校验
  6. 条件变量:使用条件变量wait方法时,必须外加条件判断,并在循环中等待,原因有2:
cpp 复制代码
1 通知丢失:线程A notify之后,线程B将一直等待下去,没有处理这次notify。
2 虚假唤醒:即使没有notify,线程B也可能会被唤醒。

优化小TIP

  1. 全局变量 复制一份给局部变量有简单优化,若全局变量较远,cache不容易获取,可能开销高于局部变量。
  2. 函数模块内,代码块优化位置调整:多个return false的并行无关联分支,建议把"最容易 return false"的分支放在最前面,减少因其return false而导致其余return true分支的动作浪费
  3. 数据结构之间,使用依赖而不是继承,可以减少继承带来的拷贝开销
  4. 小的临时局部变量,尽量不使用堆内存,因为分配堆malloc是个线程安全,带锁的函数,高并发场景下容易降低程序效率
  5. 全局变量,简单结构复制一份,增加缓存命中率;复杂结构使用指针引用,减少指令调用
  6. 复杂结构体初始化,使用模板定义后, memcopy_s而不是逐项赋值
  7. 检视时,查看for的必要性,统计信息可能不需要使用for
相关推荐
SweetCode15 小时前
【无标题】
开发语言·c++·算法
王老师青少年编程16 小时前
信奥赛C++提高组csp-s之拓扑排序详解
c++·算法·拓扑排序·csp·信奥赛·csp-s·提高组
xie_pin_an16 小时前
C++ 从入门到进阶:核心知识与实战指南
java·c++·算法
No0d1es16 小时前
2025年12月 GESP CCF编程能力等级认证C++八级真题
开发语言·c++·青少年编程·gesp·ccf
fqbqrr16 小时前
2601C++,概念与约束及推导本
c++
xiaowu08017 小时前
C#调用 C++ DLL 加载地址方式选择
开发语言·c++·c#
转基因17 小时前
C++的IO流
开发语言·c++
程序员zgh18 小时前
Linux 系统调用
linux·运维·服务器·c语言·c++·系统安全
天若有情67318 小时前
打破思维定式!C++参数设计新范式:让结构体替代传统参数列表
java·开发语言·c++