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
相关推荐
Morwit5 分钟前
【力扣hot100】 1. 两数之和
数据结构·c++·算法·leetcode·职场和发展
SpiderPex27 分钟前
第十七届蓝桥杯 C++ B组-题目 (最新出炉 )
c++·职场和发展·蓝桥杯
炘爚41 分钟前
C++ 右值引用与程序优化
开发语言·c++
si莉亚1 小时前
ROS2安装EVO工具包
linux·开发语言·c++·开源
智者知已应修善业1 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
良木生香1 小时前
【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载
开发语言·c++
小此方1 小时前
Re:从零开始的 C++ 进阶篇(三)彻底搞懂 C++ 多态:虚函数、虚表与动态绑定的底层原理
c++
忘梓.1 小时前
墨色规则与血色节点:C++红黑树设计与实现探秘
java·开发语言·c++
hhh3u3u3u1 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1
凤年徐2 小时前
C++手撕红黑树:从0到200行,拿下STL map底层核心
c++·后端·算法