news 2026/4/16 11:10:37

C++的5种高级初始化技术:从reserve到piecewise_construct等

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++的5种高级初始化技术:从reserve到piecewise_construct等

在讲解高级初始化技术之前,先看一个前置背景,使用下面的类来方便地说明何时调用它的特殊成员函数。这样,我们就能看到额外的临时对象。

展开

代码语言:C++

自动换行

AI代码解释

struct MyType { MyType() { std::cout << "MyType default\n"; } explicit MyType(std::string str) : str_(std::move(str)) { std::cout << std::format("MyType {}\n", str_); } ~MyType() { std::cout << std::format("~MyType {}\n", str_); } MyType(const MyType& other) : str_(other.str_) { std::cout << std::format("MyType copy {}\n", str_); } MyType(MyType&& other) noexcept : str_(std::move(other.str_)) { std::cout << std::format("MyType move {}\n", str_); } MyType& operator=(const MyType& other) { if (this != &other) str_ = other.str_; std::cout << std::format("MyType = {}\n", str_); return *this; } MyType& operator=(MyType&& other) noexcept { if (this != &other) str_ = std::move(other.str_); std::cout << std::format("MyType = move {}\n", str_); return *this; } std::string str_; };

现在可以从相对简单但基本的元素开始。

二、reserve 结合 emplace_back

C++中的vector是一种可以根据需要增长的动态数组。但是,每次向量增长超过其当前容量时,它可能需要重新分配内存,这代价是昂贵的。为了优化这一点,可以使用reserve()方法结合emplace_back()

reserve方法不改变vector的大小,但确保vector有足够的已分配内存来存储指定数量的元素。通过提前预留空间,可以防止在向向量添加元素时进行多次重新分配。

示例:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <string> #include <vector> #include <format> struct MyType { MyType() { std::cout << "MyType default\n"; } explicit MyType(std::string str) : str_(std::move(str)) { std::cout << std::format("MyType {}\n", str_); } ~MyType() { std::cout << std::format("~MyType {}\n", str_); } MyType(const MyType& other) : str_(other.str_) { std::cout << std::format("MyType copy {}\n", str_); } MyType(MyType&& other) noexcept : str_(std::move(other.str_)) { std::cout << std::format("MyType move {}\n", str_); } MyType& operator=(const MyType& other) { if (this != &other) str_ = other.str_; std::cout << std::format("MyType = {}\n", str_); return *this; } MyType& operator=(MyType&& other) noexcept { if (this != &other) str_ = std::move(other.str_); std::cout << std::format("MyType = move {}\n", str_); return *this; } std::string str_; }; int main() { { std::cout << "--- push_back\n"; std::vector<MyType> vec; vec.push_back(MyType("First")); std::cout << std::format("capacity: {}\n", vec.capacity()); vec.push_back(MyType("Second")); } { std::cout << "--- emplace_back\n"; std::vector<MyType> vec; vec.emplace_back("First"); std::cout << std::format("capacity: {}\n", vec.capacity()); vec.emplace_back("Second"); } { std::cout << "--- reserve() + emplace_\n"; std::vector<MyType> vec; vec.reserve(2); // Reserve space for 2 elements vec.emplace_back("First"); vec.emplace_back("Second"); } }

输出:

展开

代码语言:JavaScript

自动换行

AI代码解释

--- push_back MyType First MyType move First ~MyType capacity: 1 MyType Second MyType move Second MyType move First ~MyType ~MyType ~MyType First ~MyType Second --- emplace_back MyType First capacity: 1 MyType Second MyType move First ~MyType ~MyType First ~MyType Second --- reserve() + emplace_ MyType First MyType Second ~MyType First ~MyType Second

在这个例子中,可以看到三种插入技术之间的比较:

  • push_back()

  • emplace_back()

  • reserve()结合emplace_back

第一种情况下,必须将临时对象传递给push_back,并移动它们来初始化vector的元素。但是还有一个重新分配,因为当添加第二个元素时,vector必须增长。

相对而言,emplace_back()技术更好,更容易编写,因为没有创建临时对象。

但是,第三种选择是最有效的,因为可以预先预留空间,然后在适当的地方创建元素。

通过使用reserveemplace_back,可以确保vector在添加元素到预留容量时不需要重新分配内存。这种组合是优化性能的一种强大方式,特别是在向vector`中添加多个元素时。

三、C++ 20的constinit

constinit是一个强大的工具,用于强制常量初始化,特别是对于静态或线程局部变量。这个关键字在C++ 20中引入,它解决了C++中一个长期存在的难题:静态初始化顺序的问题。通过确保变量在编译时初始化,constinit提供了一个更可预测和更安全的初始化过程。

在其核心,constinit保证它所限定的变量在编译时被初始化。这对全局变量或静态变量尤其有益,可以确保它们不受动态初始化顺序问题的影响。

示例:

展开

代码语言:C++

自动换行

AI代码解释

#include <array> // 编译期初始化 constexpr int compute(int v) { return v*v*v; } constinit int global = compute(10); // 这个将不再起作用: // constinit int another = global; int main() { // 但允许以后更改…… global = 100; // global is not constant! // std::array<int, global> arr; }

在上面的代码中,全局变量是在编译时使用compute函数初始化的。然而,与constconstexpr不同,constinit不会使变量不可变。也就是说,虽然它的初始值是在编译时设置的,但可以在运行时对其进行修改,如main函数所示。此外,由于constinit变量不是constexpr,因此不能使用它初始化另一个constinit对象(如其他的int)。

四、Lambda表达式和初始化

C++ 14对Lambda捕获进行了重大更新,引入了在Lambda捕获子句中直接初始化新数据成员的能力。这个特性称为带有初始化器的捕获或广义Lambda捕获,它在使用Lambda时为我们提供了更大的灵活性和精度。

传统上,Lambda表达式可以从其封闭范围捕获变量。在C++ 14中,现在可以直接在捕获子句中创建和初始化新的数据成员,使Lambdas更加通用。


https://www.dongchedi.com/article/7594176187270693401
https://www.dongchedi.com/article/7594176654025589273
https://www.dongchedi.com/article/7594174513613636120
https://www.dongchedi.com/article/7594173614161723966
https://www.dongchedi.com/article/7594174316762726937
https://www.dongchedi.com/article/7594174486359114264
https://www.dongchedi.com/article/7594172209028399641
https://www.dongchedi.com/article/7594172028136112665
https://www.dongchedi.com/article/7594170708973158937
https://www.dongchedi.com/article/7594171822011318809
https://www.dongchedi.com/article/7594169237096940057
https://www.dongchedi.com/article/7594169267902857753
https://www.dongchedi.com/article/7594154183356727870
https://www.dongchedi.com/article/7594153895329448472
https://www.dongchedi.com/article/7594153335339647550
https://www.dongchedi.com/article/7594149462356804121
https://www.dongchedi.com/article/7594143242124427801
https://www.dongchedi.com/article/7594143151032959513
https://www.dongchedi.com/article/7594143310076477976
https://www.dongchedi.com/article/7594143261762585112
https://www.dongchedi.com/article/7594143234042380824
https://www.dongchedi.com/article/7594143047861420569
https://www.dongchedi.com/article/7594143261762257432
https://www.dongchedi.com/article/7594113295314305561
https://www.dongchedi.com/article/7594111799855956505
https://www.dongchedi.com/article/7594110342540673598
https://www.dongchedi.com/article/7594110249179578904
https://www.dongchedi.com/article/7594109373581492761
https://www.dongchedi.com/article/7594199698655724056
https://www.dongchedi.com/article/7594197415100793369
https://www.dongchedi.com/article/7594197322150904382
https://www.dongchedi.com/article/7594196529834181145
https://www.dongchedi.com/article/7594196856478368281
https://www.dongchedi.com/article/7594195826612781592
https://www.dongchedi.com/article/7594195431069762072
https://www.dongchedi.com/article/7594195431069270552
https://www.dongchedi.com/article/7594179258625802776
https://www.dongchedi.com/article/7594177577032991257
https://www.dongchedi.com/article/7594179258625409560
https://www.dongchedi.com/article/7594177972484309529
https://www.dongchedi.com/article/7594176579102884414
https://www.dongchedi.com/article/7594177062877839897
https://www.dongchedi.com/article/7594174721596473881
https://www.dongchedi.com/article/7594175192449008153
https://www.dongchedi.com/article/7594173652875444760
https://www.dongchedi.com/article/7594172550394069566
https://www.dongchedi.com/article/7594172678253265470
https://www.dongchedi.com/article/7594171407253275198
https://www.dongchedi.com/article/7594169982704173593
https://www.dongchedi.com/article/7594171805393650201
https://www.dongchedi.com/article/7594171076024812094
https://www.dongchedi.com/article/7594169163703271998
https://www.dongchedi.com/article/7594155915663180313
https://www.dongchedi.com/article/7594152900747100734
https://www.dongchedi.com/article/7594151966180426264
https://www.dongchedi.com/article/7594148426036904473
https://www.dongchedi.com/article/7594143100311192088
https://www.dongchedi.com/article/7594143206229705278
https://www.dongchedi.com/article/7594143047860961817
https://www.dongchedi.com/article/7594143133597205054
https://www.dongchedi.com/article/7594143172075487806
https://www.dongchedi.com/article/7594143133597073982
https://www.dongchedi.com/article/7594142854390759961
https://www.dongchedi.com/article/7594111120601039384
https://www.dongchedi.com/article/7594111426885583384
https://www.dongchedi.com/article/7594112371485393470
https://www.dongchedi.com/article/7594109925660426776
https://www.dongchedi.com/article/7594108812211438104

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/4 8:57:01

MAA助手完整使用教程:从零开始掌握游戏自动化的10大技巧

MAA助手完整使用教程&#xff1a;从零开始掌握游戏自动化的10大技巧 【免费下载链接】MaaAssistantArknights 一款明日方舟游戏小助手 项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights MAA助手是一款专为明日方舟游戏设计的智能自动化工具&…

作者头像 李华
网站建设 2026/4/12 22:29:50

Python网络自动化终极指南:从零构建智能预约工具

Python网络自动化终极指南&#xff1a;从零构建智能预约工具 【免费下载链接】auto_commemorative_coin_booking 项目地址: https://gitcode.com/gh_mirrors/au/auto_commemorative_coin_booking 在数字化时代&#xff0c;网络自动化技术正成为提升工作效率的关键利器。…

作者头像 李华
网站建设 2026/4/5 15:07:07

网页视频资源捕获工具深度解析:从技术原理到实战应用

网页视频资源捕获工具深度解析&#xff1a;从技术原理到实战应用 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为无法保存心仪的在线视频而烦恼吗&#xff1f;现代网页视频资源捕获工具彻底改变…

作者头像 李华
网站建设 2026/4/14 17:10:00

3分钟搞定键盘连击:这款防抖工具让你打字如飞

3分钟搞定键盘连击&#xff1a;这款防抖工具让你打字如飞 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 还在为键盘自动"双击&quo…

作者头像 李华
网站建设 2026/4/10 9:59:55

B站视频下载神器BBDown:零基础到高手完整指南

B站视频下载神器BBDown&#xff1a;零基础到高手完整指南 【免费下载链接】BBDown Bilibili Downloader. 一款命令行式哔哩哔哩下载器. 项目地址: https://gitcode.com/gh_mirrors/bb/BBDown 还在为无法保存B站精彩视频而烦恼吗&#xff1f;BBDown这款专业的命令行下载工…

作者头像 李华
网站建设 2026/4/12 17:20:55

数字电路状态机架构设计:手把手教程(有限状态机)

数字电路中的“大脑”&#xff1a;如何手把手设计一个高效可靠的状态机你有没有遇到过这样的情况&#xff1f;写了一个看似逻辑清晰的控制模块&#xff0c;仿真时却莫名其妙卡在某个状态不动&#xff1b;或者系统偶尔出现一次异常后就再也回不到正常流程。这类问题&#xff0c;…

作者头像 李华