C++11实用特性1
1 原始字面量
有时候在输出一个路径字符串时,编译器会将其中的部分内容识别成转义字符进行输出,可以用R “xxx(原始字符串)xxx”其中()两边的字符串可以省略。原始字面量R可以直接表示字符串的实际含义,而不需要额外对字符串做转义或连接等操作。
string str2 = R"(D:\hello\world\test.text)";
2 nullptr
在之前的C++中,为指针进行初始化的时候通常用NULL,在C语言中NULL的本质是一个(void*)0,而在C++中NULL的本质就是0,一个int类型值,底层实现为:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
因为C++中不允许一个void *指针隐式转换为其它类型指针,比如:
void *ptr1 = NULL;
int *ptr2 = ptr1;//错误
int *ptr2 = (int *)ptr1;//正确
C++11没有对这一特性进行修改,而是引入了nullptr专门用于初始化空类型指针,其可以隐式转换为其它类型的指针,从而避免了野指针(没有明确指向的指针)
3 constexpr
const在C++11之前就有,用处在于变量只读以及修饰常量,但要注意两者是不一样的
变量只读:比如函数中我们不希望传入的参数被修改
void func(const int num)
修饰常量:有时提前定义一个常量,并用于描述数组大小
const int a = 20;
int arr[a];
C++11中用constexpr修饰常量表达式,常量表达式指的就是由多个(≥1)常量(值不会改变)组成并且在编译过程中就得到计算结果的表达式。其效率高于运行时计算的非常量表达式,其不需要每次运行都计算
要注意的时是,constexpr不能取代const,在表示常量的时候,两者是相同的,但是在用于变量只读的时候,比如引用传参的时候设置只读属性还是用const,constexpr达不到修饰变量只读的效果。
4 auto自动类型推导
使用auto声明的变量必须要进行初始化,以让编译器推导出它的实际类型,在编译时将auto占位符替换为真正的类型。
auto的使用限制
- 不能作为函数参数使用。因为只有在函数调用的时候才会给函数参数传递实参,auto要求必须要给修饰的变量赋值,因此二者矛盾。
- 不能用于类的非静态成员变量的初始化
- 不能使用auto关键字定义数组
- 无法使用auto推导出模板参数
auto的应用
- 用于泛型编程,在使用模板的时候,很多情况下我们不知道变量应该定义为什么类型就用auto
- 用于stl容器的遍历
#include <map>
int main()
{
map<int, string> person;
map<int, string>::iterator it = person.begin();
for (; it != person.end(); ++it)
{
// do something
}
return 0;
}
//简化后为:
map<int, string> person;
// 代码简化
for (auto it = person.begin(); it != person.end(); ++it)
{
// do something
}
5 decltype类型推导
使用auto只能进行初始化变量的推导,而decltype可以进行表达式的推导,其也是在编译阶段实现的
推导规则
- 表达式为普通变量或者普通表达式或者类表达式,在这种情况下,使用decltype推导出的类型和表达式的类型是一致的。
- 表达式是函数调用,使用decltype推导出的类型和函数返回值一致。
- 表达式是一个左值,或者被括号( )包围,使用 decltype推导出的是表达式类型的引用(如果有const、volatile限定符不能忽略)。
6 final和override
C++中增加了final关键字来限制某个类不能被继承,或者某个虚函数不能被重写,如果使用final修饰函数,只能修饰虚函数,并且要把final关键字放到类或者函数的后面。
override关键字确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同时也明确表明将会重写基类的虚函数,这样就可以保证重写的虚函数的正确性,也提高了代码的可读性,和final一样这个关键字要写到方法的后面。使用了override关键字之后,假设在重写过程中因为误操作,写错了函数名或者函数参数或者返回值编译器都会提示语法错误
7 函数模板允许默认参数
8 using
在C++中using用于声明命名空间,使用命名空间也可以防止命名冲突。在程序中声明了命名空间之后,就可以直接使用命名空间中的定义的类了。C++11中用using可以来定义类型的别名,和typedef的效果一样
typedef 旧的类型名 新的类型名;
// 使用举例
typedef unsigned int uint_t;
using 新的类型 = 旧的类型;
// 使用举例
using uint_t = int;
其好处体现在函数指针的定义上
// 使用typedef定义函数指针
typedef int(*func_ptr)(int, double);
// 使用using定义函数指针
using func_ptr1 = int(*)(int, double);
使用using定义函数指针别名的写法看起来就非常直观了,把别名的名字强制分离到了左边,而把别名对应的实际类型放在了右边,比较清晰,可读性比较好。
但using最主要的特性还是可以通过使用using来为一个模板定义别名,比如:
template <typename T>
using mymap = map<int, T>;
使用typedef重定义类似很方便,但是它有一点限制,比如无法重定义一个模板,比如我们需要一个固定以int类型为key的map,它可以和很多类型的value值进行映射,如果使用typedef这样直接定义就非常麻烦:
typedef map<int, string> m1;
typedef map<int, int> m2;
typedef map<int, double> m3;
9 基于范围的for循环
基本语法
for (declaration : expression)
{
// 循环体
}
在上面的语法格式中declaration表示遍历声明,在遍历过程中,当前被遍历到的元素会被存储到声明的变量中。expression是要遍历的对象,它可以是表达式、容器、数组、初始化列表等。
通常建议以引用的方式进行修改,不仅可以对其进行写操作,而且还避免了每次遍历的拷贝操作。
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
vector<int> t{ 1,2,3,4,5,6 };
cout << "遍历修改之前的容器: ";
for (auto &value : t)
{
cout << value++ << " ";
}
cout << endl << "遍历修改之后的容器: ";
for (auto &value : t)
{
cout << value << " ";
}
cout << endl;
return 0;
}
对容器的遍历过程中,如果只是读数据,不允许修改元素的值,可以使用const定义保存元素数据的变量,在定义的时候建议使用const auto &,这样相对于const auto效率要更高一些。
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
vector<int> t{ 1,2,3,4,5,6 };
for (const auto& value : t)
{
cout << value << " ";
}
return 0;
}
使用普通的for循环方式(基于迭代器)遍历关联性容器, auto自动推导出的是一个迭代器类型,需要使用迭代器的方式取出元素中的键值对(和指针的操作方法相同):
- it->first
- it->second
使用基于范围的for循环遍历关联性容器,auto自动推导出的类型是容器中的value_type,相当于一个对组(std::pair)对象,提取键值对的方式如下: - it.first
- it.second
普通循环与基于范围循环的区别:
对应基于范围的for循环来说,冒号后边的表达式只会被执行一次。在得到遍历对象之后会先确定好迭代的范围,基于这个范围直接进行遍历。如果是普通的for循环,在每次迭代的时候都需要判断是否已经到了结束边界。
10
C++11实用特性1的更多相关文章
- ES6相关实用特性
本文总结ECMAScript6相关实用特性 目录 let和const 箭头函数 class 对象字段 模板字符串 解构赋值 函数参数扩展 迭代器for...of 模块加载 map和weakmap se ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- C++11新特性总结 (二)
1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...
- C++11新特性总结 (一)
1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...
- 【转】C++11常用特性的使用经验总结
出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...
- C++ 11 新特性
C++11新特性: 1.auto 2.nullptr 3.for 4.lambda表达式 5.override ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- 在C++98基础上学习C++11新特性
自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...
- C++11常用特性的使用经验总结
转自:http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++11方 ...
- [转]C++11常用特性的使用经验总结
转载出处 http://www.cnblogs.com/feng-sc C++11已经出来很久了,网上也早有很多优秀的C++11新特性的总结文章,在编写本博客之前,博主在工作和学习中学到的关于C++1 ...
随机推荐
- Docker安装与教程-Centos7(一)
复现漏洞时,经常要复现环境,VMware还原太过麻烦,所以学习docker的基本操作也是必要的 Docker三要素-镜像.容器.仓库 操作系统:Centos7 官方教程文档 1.Docker的安装与卸 ...
- Vue3 第三章
Vite目录 public 下面的不会被编译 可以存放静态资源 assets 下面可以存放可编译的静态资源 components 下面用来存放我们的组件 App.vue 是全局组件 main ts 全 ...
- 【结对作业】 第一周 | 学习体会day05
实现了单条地铁线路的直达 进行了页面的优化,实现了侧边栏功能 并且对第二天(今天)的任务进行了规划.
- excel表格怎么设置数据超链接?
在Excel表格中,可以设置超链接来快速导航到其他单元格.工作表.文件.网页等.下面我将详细介绍如何设置数据超链接. 1. 在Excel表格中选择要添加超链接的单元格或文本. 2. 使用鼠标右键点击选 ...
- httpclients 和 okhttp 区别
HttpClient使用介绍使用HttpClient发送请求主要分为以下几步骤: 创建 CloseableHttpClient对象或CloseableHttpAsyncClient对象,前者同步,后者 ...
- 【工具推荐】LICEcap –GIF 屏幕录制工具
介绍: LICEcap 是一款简洁易用的动画屏幕录制软件,支持导出 GIF 动画图片格式,轻量级.高质量(每帧颜色数量可超过256).使用简单,录制过程中可以随意改变录屏范围. LICEcap 非常轻 ...
- 容器网络Cilium:DualStack双栈特性分析
本文分享自华为云社区<容器网络Cilium入门系列之DualStack双栈特性分析>,作者: 可以交个朋友. 一 . 关于IPV6/IPV4 双栈 目前很多公司开始将自己的业务由ipv4切 ...
- Kafka核心逻辑介绍
1.概念 Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica)分布式消息系统(kafka2.8.0版本之后接触了对zk的依赖,使用自己 ...
- flask中使用pyjwt
**pyjwt使用教程: ** https://pyjwt.readthedocs.io/en/stable/ 使用案例 import datetime from flask import Flask ...
- Ubuntu 20.04 安装Odoo17
1.升级系统 sudo apt-get update 2.更新系统 sudo apt-get upgrade 3.查看系统Python3版本 python3 -V 4.更新Python3.8到3.10 ...