C++11 列表初始化与类型声明

目录

0.前言

1.C++11介绍

2.统一的列表初始化

2.1{}初始化

2.2initializer_list

2.2.1initializer_list 的基本用法

2.2.2用于类的 initializer_list 构造函数

2.2.3与标准库容器的结合

2.2.4优势与注意事项

3.新声明

3.1auto

3.1.1基本用法

3.1.2优势

3.1.3注意事项

3.2decltype

3.2.1基本用法

3.2.2与 auto 的区别

3.2.3用于返回类型推导

3.3nullptr

3.3.1基本用法

3.3.2与 NULL 的区别

3.3.3优势

4.小结


(图源网络,侵删)

0.前言

在现代软件开发中,数据结构和编程语言的特性直接影响代码的效率和可维护性。尽管 C++98 提供了丰富的数据结构和功能,但在代码简洁性和类型安全性方面仍有不足。C++11 引入了许多新特性,如右值引用、lambda 表达式、智能指针和多线程库等,极大地增强了语言的现代化和功能性。本文将重点介绍 C++11 的列表初始化和类型声明新特性,通过实例展示它们的用法和优势,帮助开发者更好地理解和应用这些特性。

1.C++11介绍

C++11,也被称为 C++0x,是 C++ 标准的一次重要更新,于 2011 年正式发布。它的出现标志着 C++ 语言的一个重大转折点,旨在解决 C++98 中的各种局限性和问题,使 C++ 更加现代化和高效。C++11 的开发始于 2005 年,其目标是提升语言的性能和可用性,同时保持与现有代码的兼容性。标准委员会通过广泛的讨论和实验,引入了大量的新特性,包括右值引用(Rvalue References)、lambda 表达式、智能指针、多线程库、以及更为简洁和安全的初始化和类型声明方式。C++11 不仅极大地丰富了语言本身的功能,也为开发者提供了更为强大的工具,帮助他们编写更高效、更可靠的代码。

2.统一的列表初始化

C++11 引入了统一的列表初始化语法,使得对象的初始化方式更加一致和简洁。新的列表初始化方式通过使用花括号 {} 来统一不同类型对象的初始化过程,从而简化代码,减少错误。

2.1{}初始化

在 C++11 之前,初始化对象的方式因对象类型的不同而各异。对于基本类型、数组、结构体、类等,各自有不同的初始化语法。这种多样化的初始化方式不仅让代码显得杂乱无章,还容易引发各种隐式转换错误和未定义行为。C++11 的 {} 初始化通过提供一种统一的语法,解决了这些问题。

基本类型的初始化

在 C++11 中,花括号 {} 可以用于初始化基本类型:

int a{10};    // 直接初始化
int b = {20}; // 复制初始化
int c{};      // 值初始化,c 被初始化为 0

这种初始化方式的一个显著优点是,它能够防止窄化转换(narrowing conversion):

int x{3.14};  // 错误:不能将 double 赋值给 int
int y = 3.14; // 有效,但 y 被截断为 3

 通过使用 {} 初始化,编译器会检测并阻止潜在的错误转换,增强了代码的安全性。

类和结构体的初始化

C++11 的 {} 初始化同样适用于类和结构体对象:

struct Point {int x;int y;
};Point p1{1, 2};  // 直接初始化
Point p2 = {3, 4}; // 复制初始化

对于类对象,C++11 允许通过 {} 初始化来调用构造函数:

class MyClass {
public:MyClass(int a, int b) : x(a), y(b) {}
private:int x, y;
};MyClass obj{10, 20}; // 调用 MyClass 的构造函数

数组和容器的初始化

C++11 使得数组和标准库容器的初始化更加简洁和直观:

int arr[] = {1, 2, 3, 4, 5};   // 数组初始化
std::vector<int> vec{1, 2, 3, 4, 5}; // std::vector 初始化
std::map<int, std::string> m = {{1, "one"},{2, "two"},{3, "three"}
}; // std::map 初始化

这种统一的列表初始化方式不仅简化了代码,还增强了代码的可读性和一致性,使开发者能够更轻松地管理复杂的数据结构。 

2.2initializer_list

C++11 引入了 initializer_list 类型,以支持更加灵活和统一的列表初始化。initializer_list 是标准库中的一个模板类,允许构造函数和其他函数接收一个初始化列表,从而简化了容器和对象的初始化过程。

2.2.1initializer_list 的基本用法

initializer_list 提供了一种方式,使得函数可以接收一组由花括号 {} 包裹的初始值。以下是一个简单的示例:

#include <initializer_list>
#include <iostream>void printList(std::initializer_list<int> list) {for (auto elem : list) {std::cout << elem << " ";}std::cout << std::endl;
}int main() {printList({1, 2, 3, 4, 5});return 0;
}

在这个例子中,函数 printList 接受一个 initializer_list<int> 类型的参数,并通过范围循环(range-based for loop)来遍历并打印列表中的元素。

2.2.2用于类的 initializer_list 构造函数

initializer_list 常用于定义容器类的构造函数,使得容器类可以接受初始化列表,从而简化对象的初始化。例如:

#include <initializer_list>
#include <vector>
#include <iostream>class MyContainer {
public:MyContainer(std::initializer_list<int> list) {for (auto elem : list) {data.push_back(elem);}}void print() const {for (auto elem : data) {std::cout << elem << " ";}std::cout << std::endl;}private:std::vector<int> data;
};int main() {MyContainer container = {1, 2, 3, 4, 5};container.print();return 0;
}

 在这个例子中,MyContainer 类的构造函数接受一个 initializer_list<int> 类型的参数,并使用该列表初始化 data 成员。这样,用户可以直接使用花括号语法来初始化 MyContainer 对象。

2.2.3与标准库容器的结合

initializer_list 在标准库容器中得到了广泛应用。例如,std::vectorstd::setstd::map 等容器都支持通过 initializer_list 进行初始化:

#include <vector>
#include <set>
#include <map>
#include <iostream>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};std::set<std::string> strSet = {"one", "two", "three"};std::map<int, std::string> intToStrMap = {{1, "one"},{2, "two"},{3, "three"}};for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;for (const auto& str : strSet) {std::cout << str << " ";}std::cout << std::endl;for (const auto& pair : intToStrMap) {std::cout << pair.first << ": " << pair.second << " ";}std::cout << std::endl;return 0;
}

输出结果:

1 2 3 4 5
one three two
1: one 2: two 3: three 

在这个示例中,std::vectorstd::setstd::map 都通过 initializer_list 进行了初始化,使得代码更加简洁和易读。

2.2.4优势与注意事项

使用 initializer_list 具有以下几个优势:

  1. 简洁性:通过花括号 {} 初始化列表,使得代码更加简洁和直观。
  2. 一致性:提供了一种统一的初始化语法,适用于各种类型的对象。
  3. 安全性:避免了某些类型转换问题,提高了代码的安全性。

然而,使用 initializer_list 时也需注意以下几点:

  1. 不可修改initializer_list 本身是不可修改的,不能添加或删除元素。
  2. 生命周期initializer_list 的元素是对外部数组的引用,使用时需要确保数组的生命周期长于 initializer_list

3.新声明

C++11 引入了几种新的类型声明方式,使得代码更加简洁和易于维护。新的类型声明方式包括 autodecltypenullptr,它们极大地增强了 C++ 语言的类型推导能力和代码安全性。

3.1auto

auto 关键字允许编译器根据初始化表达式自动推导变量的类型,从而简化了变量声明,特别是在复杂类型的声明中。

3.1.1基本用法

auto 可以用于推导任何类型的变量,包括基本类型、指针、引用、容器迭代器等:

int x = 10;
auto a = x;  // a 被推导为 int 类型double y = 5.5;
auto b = y;  // b 被推导为 double 类型auto c = &x;  // c 被推导为 int* 类型std::vector<int> vec = {1, 2, 3};
auto it = vec.begin();  // it 被推导为 std::vector<int>::iterator 类型

3.1.2优势

使用 auto 的优势包括:

  1. 简化代码:减少冗长的类型声明,特别是在使用 STL 容器和迭代器时。
  2. 提高可读性:让代码更简洁,更易读。
  3. 减少错误:降低手动写错类型的风险,特别是在类型复杂或容易变化时。

3.1.3注意事项

尽管 auto 带来了诸多便利,但在使用时需要注意以下几点:

  1. 明确性:在某些情况下,auto 可能会降低代码的明确性和可读性,需要开发者对推导出的类型有清晰的认识。

  2. 推导规则auto 会根据右值表达式推导类型,有时可能会与预期不符。例如,数组类型会被推导为指针类型:

    int arr[3] = {1, 2, 3};
    auto p = arr;  // p 被推导为 int*
    

3.2decltype

decltype 关键字用于查询表达式的类型,并返回该类型。它在泛型编程和模板编程中尤为有用,可以精确地推导出变量或表达式的类型。

3.2.1基本用法

decltype 主要用于变量声明、函数返回类型推导等:

int x = 10;
decltype(x) y = 20;  // y 的类型与 x 相同,都是 intconst int& z = x;
decltype(z) w = x;  // w 的类型与 z 相同,都是 const int&

3.2.2与 auto 的区别

auto 是根据初始化表达式推导类型,而 decltype 则是根据表达式的类型进行推导。以下是一个对比示例:

int x = 10;
auto a = x;       // a 是 int
decltype(x) b = x; // b 是 intconst int& y = x;
auto c = y;       // c 是 int,丢弃了 const 和引用
decltype(y) d = y; // d 是 const int&

3.2.3用于返回类型推导

在模板编程中,decltype 常用于推导函数的返回类型:

template <typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {return a + b;
}

3.3nullptr

C++11 引入了 nullptr 关键字,用于表示空指针,替代了传统的 NULL 宏。nullptr 是一个类型安全的空指针字面值,避免了 NULL 可能引发的类型转换问题。

3.3.1基本用法

nullptr 可以与任意指针类型兼容:

int* p1 = nullptr;  // int* 类型的空指针
double* p2 = nullptr;  // double* 类型的空指针void func(int* ptr) {if (ptr == nullptr) {std::cout << "Pointer is null" << std::endl;}
}int main() {func(nullptr);  // 安全地传递空指针return 0;
}

3.3.2与 NULL 的区别

NULL 宏通常定义为 0(void*)0,在某些情况下可能引发类型不匹配的问题:

void f(int);
void f(void*);f(0);      // 调用 f(int)
f(NULL);   // 调用 f(int),可能意图是 f(void*)
f(nullptr); // 调用 f(void*),避免了歧义

3.3.3优势

使用 nullptr 的优势包括:

  1. 类型安全:避免了 NULL 引发的类型转换问题。
  2. 代码清晰:显式表示指针为空,使代码更具可读性。

4.小结

C++11 引入的列表初始化和新的类型声明方式,使得 C++ 语言更加强大和易用。花括号 {} 初始化和 initializer_list 提供了统一的初始化方式,简化了对象的创建过程;而 autodecltypenullptr 则增强了类型推导能力,减少了代码中的冗余和错误。掌握这些新特性,可以显著提高 C++ 编程的效率和代码质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

npm国内淘宝镜像registry镜像过期

我们在使用npm的时候会遇到淘宝镜像安装过期的问题 首先了解 npm 淘宝镜像是一个 npm 注册表的镜像&#xff0c;用于加速 npm 包的下载。 一、如何设置&#xff1f; 如何设置淘宝镜像&#xff1f;淘宝镜像已经从 registry.npm.taobao.org 切换到了 registry.npmmirror.com n…

贪吃蛇 C++简易版(完整代码)

代码&#xff1a; #include <iostream> #include <conio.h> #include <vector> #include <windows.h> #include <ctime>using namespace std; //设置范围 const int WIDTH 20; const int HEIGHT 20;const char EMPTY ; const char SNAKE O…

代码随想录总结

文章目录 1. 回溯法1.1 组合1.2 组合总和31.3 电话号码的字母组合 2. 1. 回溯法 经典问题&#xff1a;排列、组合、切割、子集、棋盘 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节点孩子的数量就是集合的…

【SpringBoot教程:从入门到精通】掌握Springboot开发技巧和窍门(四)-Vue项目配置环境、导航栏

主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; 文章目录 前言 Vue项目配置环境 安装依赖 创建菜单 总结 前言 主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; Vue项目配置环境 安装…

【状语从句】

框架 概念&#xff0c;特点主将从现连接词时间条件地点结果方式让步原因目的比较省略倒装 解读 1【概念&#xff0c;特点】 一个完整的句子&#xff0c;去修饰另一个完整句子中的动词&#xff0c;称为状语从句&#xff1b;特点&#xff1a;从句完整&#xff0c;只用考虑连接词是…

Git远程仓库推送

这里我只连接了两个站点的远程仓库&#xff0c;一个是国内的Gitee&#xff0c;另一个是Github&#xff0c;这两个站点的连接方式主要有两种&#xff0c;第一种就是通过https来连接远程仓库&#xff0c;另一种是通过ssh公钥来连接&#xff0c;这两个站点练接的大致过程都是一样的…

Acrel-1000DP分布式光伏监控系统在江苏盛佳德新材料有限公司4.03MW分布式光伏10KV并网系统的应用

安科瑞戴婷 Acrel-Fanny 摘要&#xff1a;随着我国社会的不断进步,经济得到迅速的发展,城市化进程也逐渐加快。城市电力配电网络的供电压力逐渐增加,传统的发电技术已经不再适用于目前城市电力配电的发展现状。传统发电技术电力转化的效率比较低,对空气的污染也比较大,不利于城…

如何使用大语言模型绘制专业图表

过去的一年里&#xff0c;我相信大部分人都已经看到了大语言模型(后文简称LLM)所具备的自然语言理解和文本生成的能力&#xff0c;还有很多人将其应用于日常工作中&#xff0c;比如文案写作、资料查询、代码生成……今天我要向大家介绍LLM的一种新使用方式——绘图。这里说的绘…

SpringBoot整合PowerJob 实现远程任务

PowerJob介绍 PowerJob 是全新一代分布式任务调度和计算框架&#xff0c;提供了可视化界面&#xff0c;可通过单机、远程等形式调用任务并提供了运行监控和日志查看的功能模块&#xff0c;是当前比较流行的分布式定时任务框架之一&#xff1b; PowerJob 官网文档地址 环境搭建…

DC系列靶场---DC 3靶场的渗透测试(一)

信息收集 Nmap扫描 nmap -sS -sV -T4 -p- -O 172.30.1.142//-sS TCP的SYN扫描 //-sV 服务版本检测 //-T4 野蛮的扫描&#xff08;常用&#xff09; //-O 识别操作系统 使用Nmap扫描只看到一个80端口&#xff0c;Apache的2.4.18版本。 http探测 使用Wappalyzer插件可以到…

OSMDroidOfflineDemo源码调试记录

文章目录 源码下载环境配置尝试不同离线加载遇到的问题 尝试安卓端加载离线地图&#xff0c;下载了使用osmdroid的离线版项目源码&#xff0c;更改JDK环境、gradle环境&#xff0c;一顿操作下来&#xff0c;踉踉跄跄的把程序跑起来了&#xff0c;但是离线的地图一直加载不出来。…

机器人笛卡尔空间阻抗控制

机器人笛卡尔空间阻抗控制是一种重要的机器人控制策略,它关注于机器人末端执行器在笛卡尔空间(即任务空间)内的动态特性,以实现与环境的柔顺交互。以下是对机器人笛卡尔空间阻抗控制的详细解释: 一、基本概念 笛卡尔空间:指机器人末端执行器(如手爪、工具等)所处的三维…

QT基础教程(QEvent事件和事件过滤器)

文章目录 前言一、具体介绍二、具体案例1.鼠标事件2.键盘事件3.窗口事件 三、事件过滤器事件过滤器的工作原理 总结 前言 本篇文章将带大家来学习QT中的QEvent事件&#xff0c;QEvent 是 Qt 框架中的一个核心类&#xff0c;用于处理各种事件。在 Qt 的事件处理系统中&#xff…

C++学习日记 | LAB 10 运算符重载与友元函数

资料来源&#xff1a;南科大 于仕琪 C/C Program Design LINK&#xff1a;CPP/week10 at main ShiqiYu/CPP GitHub 一、本节内容 本节首先以一个例子具体演示和回顾操作符重载、友元函数以及重载<<操作符。习题部分则为各种运算符重载以及输入输出重载 1.1 Operator o…

nginx 版本升级

Nginx 的版本最开始使用的是 Nginx-1.18.0 &#xff0c; 由于服务升级&#xff0c;需要将 Nginx 的版本升级到 Nginx-1.19.7 &#xff0c;要求 Nginx 不能中断提供服务。 为了应对上述的需求&#xff0c;提供两种解决方案&#xff1a; 方案1&#xff1a; make upgrade 完成升…

包装类和泛型

&#x1f389;欢迎大家收看&#xff0c;请多多支持&#x1f339; &#x1f970;关注小哇&#xff0c;和我一起成长&#x1f680;个人主页&#x1f680; 包装类&#x1f319; Java中每个基本数据类型都对应了一个包装类&#xff0c; 除了int的包装类是Integer&#xff0c;char…

STM32项目分享:智能风扇系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.com/video/BV1xw4m1Y7sA…

详解 @RequestHeader 注解在 Spring Boot 中的使用

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…

springboot鲜花商城平台-计算机毕业设计源码56085

基于微信小程序的鲜花商城平台设计与实现 摘 要 鲜花商城小程序的研究旨在设计和开发一个方便、快捷的移动应用平台&#xff0c;为用户提供鲜花购买、资讯浏览和社交互动等功能。该研究包括以下几个方面的内容&#xff1a;首先&#xff0c;通过调研和分析鲜花市场和用户需求&a…

【你也能从零基础学会网站开发】 SQL结构化查询语言应用基础--DDL篇--SQL Server数据库开发之ALTER TABLE修改表语句使用详解

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 ALTER TABLE 语…