news 2026/4/18 3:37:49

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/18 8:43:53

PCL2-CE启动器终极配置指南:释放Minecraft游戏性能潜力

PCL2-CE启动器终极配置指南&#xff1a;释放Minecraft游戏性能潜力 【免费下载链接】PCL2-CE PCL2 社区版&#xff0c;可体验上游暂未合并的功能 项目地址: https://gitcode.com/gh_mirrors/pc/PCL2-CE 还在为Minecraft启动器卡顿、功能单一而烦恼吗&#xff1f;PCL2-CE…

作者头像 李华
网站建设 2026/4/18 8:47:11

OpenSpeedy:重新定义游戏时间流速的智能加速方案

OpenSpeedy&#xff1a;重新定义游戏时间流速的智能加速方案 【免费下载链接】OpenSpeedy 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy 你是否曾经在游戏中陷入这样的困境&#xff1a;重复刷怪时感到时间漫长&#xff0c;挑战高难度Boss时反应不及&#x…

作者头像 李华
网站建设 2026/4/9 1:32:00

Windows平台终极PDF解决方案:Poppler完整使用指南

Windows平台终极PDF解决方案&#xff1a;Poppler完整使用指南 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 还在为PDF文档处理烦恼吗&#xff1f…

作者头像 李华
网站建设 2026/4/18 8:48:54

PCL2-CE社区版启动器:解锁Minecraft游戏体验的全新境界

PCL2-CE社区版启动器&#xff1a;解锁Minecraft游戏体验的全新境界 【免费下载链接】PCL2-CE PCL2 社区版&#xff0c;可体验上游暂未合并的功能 项目地址: https://gitcode.com/gh_mirrors/pc/PCL2-CE 还在为Minecraft启动器的性能瓶颈和功能限制而困扰吗&#xff1f;P…

作者头像 李华
网站建设 2026/4/17 19:07:36

ncmdump终极指南:3步搞定网易云音乐NCM转MP3

ncmdump终极指南&#xff1a;3步搞定网易云音乐NCM转MP3 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐的加密格式烦恼吗&#xff1f;想要在任意设备上畅听个人收藏的音乐&#xff1f;ncmdump正是你需要的专业工具…

作者头像 李华
网站建设 2026/4/18 6:49:20

E-Hentai漫画批量下载完整指南:如何快速建立个人收藏库

E-Hentai漫画批量下载完整指南&#xff1a;如何快速建立个人收藏库 【免费下载链接】E-Hentai-Downloader Download E-Hentai archive as zip file 项目地址: https://gitcode.com/gh_mirrors/eh/E-Hentai-Downloader 还在为E-Hentai上心爱的漫画无法高效下载而困扰吗&a…

作者头像 李华