当前位置: 首页 > news >正文

Effective C++ 条款26: 尽可能延后变量定义式的出现时间

Effective C++ 条款26:尽可能延后变量定义式的出现时间


核心思想将变量定义推迟到真正需要使用它的时刻,并在定义时直接初始化,避免不必要的构造函数/析构函数调用开销,提升程序效率与资源利用率。

⚠️ 1. 过早定义的性能代价

不必要的构造/析构开销

std::string encryptPassword(const std::string& password) {using namespace std;string encrypted;  // 过早定义(此时尚未使用)if (password.length() < MinimumLength) {throw logic_error("Password too short");}encrypted = password;         // 赋值操作encrypt(encrypted);           // 加密处理return encrypted;
}

性能分析

  1. 即使抛出异常 → encrypted仍被构造和析构
  2. 先默认构造 + 再赋值 → 效率低于直接构造

循环中的性能陷阱

// 方式A:循环外定义
Widget w;
for (int i = 0; i < n; ++i) {w = getWidget(i);  // 赋值操作process(w);
}  // 1次构造 + n次赋值 + 1次析构// 方式B:循环内定义
for (int i = 0; i < n; ++i) {Widget w = getWidget(i);  // 构造操作process(w);
}  // n次构造 + n次析构

🚨 2. 解决方案:延后定义+直接初始化

安全高效实现

std::string encryptPassword(const std::string& password) {if (password.length() < MinimumLength) {throw logic_error("Password too short");}// 延后定义 + 直接初始化std::string encrypted = password;  // 拷贝构造encrypt(encrypted);                // 修改对象return encrypted;
}  // 仅1次构造+1次析构

循环场景优化

// 情况1:赋值成本 < 构造+析构成本 → 循环外定义
Widget w;
for (int i = 0; i < n; ++i) {w = getWidget(i);  // 高效赋值process(w);
}// 情况2:赋值成本高 → 循环内定义
for (int i = 0; i < n; ++i) {Widget w(getWidget(i));  // 移动构造/直接初始化process(w);
}// 情况3:支持移动语义 → 循环内定义更优
for (int i = 0; i < n; ++i) {auto w = createWidget(i);  // 直接构造process(std::move(w));
}

⚖️ 3. 关键原则与性能权衡
定义策略适用场景性能特点
延后定义+初始化函数局部变量避免不必要的构造/析构
循环外定义赋值成本低 + 构造成本高1构造 + n赋值 + 1析构
循环内定义赋值成本高 + 构造成本低n构造 + n析构
移动语义定义类型支持高效移动(C++11+)n移动构造 + n析构

现代C++优化技巧

// 场景1:条件初始化
auto value = [&] {if (condition) return computeValueA();else return computeValueB();
}();  // IIFE立即调用函数表达式// 场景2:复杂初始化
auto config = [&] {Config cfg;cfg.loadDefaults();if (userOverride) cfg.merge(userConfig);return cfg;
}();// 场景3:结构化绑定(C++17)
auto [min, max] = findMinMax(data);

资源获取即初始化(RAII)

// 文件处理:定义即初始化
{std::ofstream logFile("debug.log");  // 获取资源logFile << "Start processing\n";     // 使用资源
}  // 自动释放资源// 锁管理:作用域控制
void criticalSection() {std::lock_guard<std::mutex> lock(mtx);  // 延后到需要时定义modifySharedData();
}  // 自动释放锁

💡 关键原则总结

  1. 定义即使用原则
    • 变量定义点应紧邻首次使用点
    • 避免在控制流分支前定义变量
  2. 直接初始化优先
    • 使用拷贝构造而非默认构造+赋值
    • 利用移动语义减少拷贝开销
  3. 循环场景权衡
    • 比较赋值成本 vs 构造+析构成本
    • 移动语义改变传统权衡标准
  4. 作用域最小化
    • 将变量限制在最小必要作用域
    • 增强代码可读性和安全性

错误模式重现

void processData(const Data& input) {Logger log;  // 过早定义(可能不使用)Validator validator;  // 构造开销大if (!input.isValid()) return;  // 提前返回 → 不必要的构造/析构log.write("Start processing");validator.check(input);// ...
}

安全重构方案

void processData(const Data& input) {if (!input.isValid()) return;  // 提前返回无开销// 延后定义Logger log("process.log");  // 定义即使用log.write("Start processing");Validator validator(input);  // 直接初始化validator.check();// 现代C++:仅在需要时获取资源auto dbConnection = [&] {if (needDB) return openDatabase();return DatabaseConnection(nullptr);}();
}// 循环优化示例
void batchProcess(const std::vector<Request>& requests) {// 情况:Widget移动成本低 → 循环内定义for (const auto& req : requests) {Widget w = createWidget(req);  // 移动构造w.process();}// 情况:Validator复用成本低 → 循环外定义Validator validator;for (const auto& req : requests) {validator.reset();validator.validate(req);}
}
http://www.lryc.cn/news/611757.html

相关文章:

  • RN项目环境搭建和使用-Mac版本(模拟器启动不起来的排查)
  • Solidity 编程进阶
  • 阿里国际招AI产品经理咯
  • 用 “私房钱” 类比闭包:为啥它能访问外部变量?
  • Google Chrome <139.0.7236.0 UAF漏洞
  • RabbitMQ面试精讲 Day 12:镜像队列与Quorum队列对比
  • MATLAB下载教程MATLAB R2025a 保姆级安装步骤(附安装包)
  • 双馈和永磁风机构网型跟网型联合一次调频并入同步机电网,参与系统一次调频,虚拟惯量下垂,虚拟同步机VSG控制matlab/simulink
  • matlab——simulink学习(5向NXP库中添加新模块)
  • 计算机网络:如何判断B或者C类IP地址是否划分了子网
  • Linux之Shell脚本基本语法
  • 3步学会使用渲染101--3DMAX云渲染
  • 【计算机网络 | 第3篇】物理媒介
  • 【数据结构与算法-Day 12】深入浅出栈:从“后进先出”原理到数组与链表双实现
  • 探索Linux MMC子系统的奥秘
  • TypeScript 元组类型精简知识点
  • 大数据存储域——HDFS存储系统
  • MCP协议与Spring AI框架实战
  • NY112NY117美光固态闪存NY119NY123
  • 新手向:Python实现简易计算器
  • 疯狂星期四文案网第30天运营日记
  • mysql索引的用法
  • Suno API V5模型 python源码 —— 使用灵感模式进行出创作
  • 国产3D大型装配设计新突破①:图纸打开设计双加速 | 中望3D 2026
  • rsync 的三种常见用法
  • 学习bug
  • jmm 指令重排 缓存可见性 Volatile 内存屏障
  • word2vector细致分解(CBOW, SKIP_GRAM, 层次soft Max, 负采样)
  • linux创建虚拟内存
  • Linux Vim 常用快捷键