C++11入门

news2024/11/28 18:38:27

目录

C++11简介

统一的列表初始化

{}初始化

std::initializer_list

文档介绍

std::initializer_list的类型

使用场景

        initializer_list接口函数模拟实现

auto与decltype

nullptr

范围for

STL的变化

新容器

新方法

新函数


C++11简介

1.在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。
2.相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习。 

统一的列表初始化

{}初始化

        在C++98中,标准允许使用{} 对数组或者结构体元素进行统一的列表初始值设定。
struct Point
{
    int _x;
    int _y;
};

int main()
{
    int array1[] = { 1, 2, 3, 4, 5 };
    int array2[5] = { 0 };
    Point p = { 1, 2 };

    return 0;
}
        C++11扩大了初始化列表的使用范围,可用于所有的内置类型和自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。
struct Point
{
    int _x;
    int _y;
};

int main()
{
    int x1 = 1;
    int x2{ 2 };

    int array1[]{ 1, 2, 3, 4, 5 };
    int array2[5]{ 0 };

    Point p{ 1, 2 };

    //也适用于new表达式
    int* pa = new int[4]{ 0 };
    return 0;
}
int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	vector<int> v2 = { 1, 2, 3, 4 };
	list<int> lt1 = { 1, 2, 3, 4, 5 };
	pair<string, string> kv("left", "左边");
	pair<string, string> kv1{ "left", "左边" };
	map<string, string> dict = { { "insert", "插入" }, kv, make_pair("list", "列表") };
	v2 = { 10, 20, 30 };

	initializer_list<int> ilt = { 1, 2, 3, 4, 5, 6, 7 };

	return 0;
}

        支持隐式类型的转换

//单参数
class A
{
public:
	//explicit A(int a)
	//	:_a(a)
	//{}

	A(int a)
		:_a(a)
	{}
private:
	int _a;
};

//多参数
struct Point
{
	int _x;
	int _y;

	Point(int x, int y)
		:_x(x)
		, _y(y)
	{
		cout << "Point(int x, int y)" << endl;
	}
	 
	//explicit Point(int x, int y)
	//	:_x(x)
	//	, _y(y)
	//{
	//	cout << "Point(int x, int y)" << endl;
	//}
};


int main()
{
	//单参数构造函数支持隐式类型转换
	A aa1(1);
	A aa2 = 2;
	string s1("hello");
	string s2 = "world";

	vector<string> v;
	v.push_back(s1);
	v.push_back("world");

	//C++11
	Point p1(1, 2);
	//多参数构造函数,支持隐式类型转换
	Point p2 = { 1, 2 };
	Point p3{ 1, 2 };

	int a = 1;
	int b = { 2 };
	int c{ 3 };
	int array1[]{1, 2, 3, 4, 5};
	int array2[5]{ 0 };

	int* ptr1 = new int[5]{1, 2, 3};
	Point* ptr2 = new Point[2]{{ 1, 1 }, { 2, 2 }};

	return 0;
}

std::initializer_list

文档介绍

std::initializer_list的类型

int main()
{
    // the type of il is an initializer_list 
    auto il = { 10, 20, 30 };
    cout << typeid(il).name() << endl;

    return 0;
}

使用场景:

        std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加了std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator= 的参数,这样就可以用大括号赋值。
int main()
{
    vector<int> v = { 1, 2, 3, 4 };
    list<int> lt = { 1, 2 };

    // 这里{"sort", "排序"}会先初始化构造一个pair对象
    map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };

    // 使用大括号对容器赋值
    v = {10, 20, 30};

    return 0;
}

        这些容器之所以能够支持这样子的列表初始化实际上是因为容器的成员函数当中增加了一个以initializer_list为参数的构造函数

        实际上就是先通过initializer_list构造出来一个列表,然后将这个列表中的所有元素拷贝到要构造的容器当中

initializer_list接口函数模拟实现

        vector容器中模拟这个构造函数

vector(initializer_list<T> il)
{
	_start = new T[il.size()];
	_finish = _start;
	_endofstorage = _start + il.size();

	for (auto x : il)
	{
		push_back(e);
	}
}

        如果我们要实现等于号操作支持列表初始化也可以进行一个函数重载

vector<T>& operator=(initializer_list<T> il)
{
	vector<T> tmp(il);

	std::swap(_start, tmp._start);
	std::swap(_finish, tmp._finish);
	std::swap(_endofstorage, tmp._endofstorage);

	return *this;
}

        假如我们使用迭代器遍历,由于使用了模板参数,所以我们在声明类型的时候要加上typename 告知编译器这是一个类型

auto与decltype

        在C++11中 auto关键字的作用是自动推导类型

map<int, string> m;
map<int, string>::iterator it = m.begin();
auto it = m.begin();
         关键字decltype将变量的类型声明为表达式指定的类型
int main()
{
	const int x = 1;
	double y = 2.2;
	//cout << typeid(x).name() << endl;
	decltype(x) z = 2;

	decltype(x * y) ret;     //ret的类型是double
	decltype(&x) p;          //p的类型是int*

	int(*pfunc1)(int) = func;
	auto pfunc2 = func;
	decltype(pfunc2) pfunc3 = func;
	decltype(&func) pfunc4 = func;

	map<string, string> dict = { { "sort", "排序" }, { "insert", "插入" } };
	auto it = dict.begin();
	//decltype的一个使用场景
	//decltype(it) copyIt = it;
	auto copyIt = it;
	vector<decltype(it)> v;
	v.push_back(it);

	return 0;
}

nullptr

        在C语言中NULL 即空指针 被定义成了0 但是这在一些情况下可能会带来一些问题

比如下面代码:

void f(int arg)
{
	cout << "void f(int arg)" << endl;
}

void f(int* arg)
{
	cout << "void f(int* arg)" << endl;
}

int main()
{
	f(NULL);    
	return 0;
}

        当我们向函数参数中传递一个空指针的时候实际上我们是想要调用第二个函数,可是结果却不符合我们的预期,于是C++11的标准中引入了nullptr来代表空指针,使得我们写的代码更加的严谨

#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

范围for

        语法格式如下
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(4);
v.push_back(7);

for (auto x : v)
{
	cout << x << endl;
}
  • auto关键字可以自动推导类型,当然我们也可以手动写出类型
  • x为变量名,它代表的是容器中的每个数据
  • 变量名和容器名之间用冒号隔开
        一个容器可以被迭代器遍历,那么它就可以使用范围for

STL的变化

新容器

array

        它的本质是一个静态的数组
int main()
{
	int a1[10];
	array<int, 10> a2;
	cout << sizeof(a2) << endl;

	//支持迭代器
	//对于越界的检查
	a1[14] = 0;       // *(a1 + 14) = 0;
	//a2[14] = 0;       // a2.operator[](14) = 0;

	return 0;
}

array和普通数组的对比

相同点:

        它和普通数组一样支持通过下标访问操作符[]来访问数据,支持范围for,并且创建后的数组大小不可改变

不同点:

        它使用一个类对于array容器进行了封装,对于数组边界的检查更加严格了,如果使用下标访问操作符越界会出现断言检查,如果使用 at 成员函数访问会抛出异常

forward_list

        它的本质是一个单链表

1.只支持头插头删,因为单链表的尾插尾删时间复杂度是O(N),而头插头删的时间复杂度则是     O(1)
2.forward_list容器提供的插入函数叫做insert_after,是在指定元素的后面插入一个元素 
3.forward_list容器提供的删除函数叫做erase_after,是在指定元素的后面删除一个元素

unordered_map和unordered_set

可以参考我之前的博客

unordered_map和unordered_set的容器使用

新方法

C++容器中提供了一些新方法

1.提供了一个以initializer_list作为参数的构造函数,用于支持列表初始化
2.提供了cbegin和cend方法,用于返回const迭代器
3.提供了emplace系列方法,并在容器原有插入方法的基础上重载了一个右值引用版本的插入函数 用于提高向容器中插入元素的效率

新函数

to_string()

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

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

相关文章

【浅学Redis】缓存 以及 缓存穿透、缓存击穿、缓存雪崩

缓存 以及 缓存击穿、缓存穿透、缓存雪崩1. 缓存1.1 缓存的作用1.2 缓存的应用场景1.3 引入缓存后的执行流程1.4 缓存的优点2. 缓存穿透2.1 场景2.2 解决策略1. 参数校验2. 缓存空值3. 缓存击穿3.1 场景3.2 解决策略4. 缓存雪崩4.1 场景4.2 解决策略5. 上面三者的区别1. 缓存 …

图像分割--入门了解

一. 三种分割 1. 语义分割&#xff08;semantic segmentation&#xff09; 语义分割&#xff1a;语义分割通过对图像中的每个像素进行密集的预测、推断标签来实现细粒度的推理&#xff0c;从而使每个像素都被标记为一个类别&#xff0c;但不区分属于相同类别的不同实例。 比…

ChatGPT之父:世界正被他搅动

阿尔特曼&#xff08;左&#xff09;与马斯克Mac LC2电脑ChatGPT这款聊天应用程序最近太火了&#xff01; 美国北密歇根大学的一名学生用它生成了一篇哲学课小论文&#xff0c;“惊艳”了教授&#xff0c;还得到了全班最高分。美国一项调查显示&#xff0c;53%的学生用它写过论…

Vue (2)

文章目录1. 模板语法1.1 插值语法1.2 指令语法2. 数据绑定3. 穿插 el 和 data 的两种写法4. MVVM 模型1. 模板语法 root 容器中的代码称为 vue 模板 1.1 插值语法 1.2 指令语法 图一 &#xff1a; 简写 &#xff1a; v-bind: 是可以简写成 &#xff1a; 的 总结 &#xff1a; …

Springboot + RabbitMq 消息队列

前言 一、RabbitMq简介 1、RabbitMq场景应用&#xff0c;RabbitMq特点 场景应用 以订单系统为例&#xff0c;用户下单之后的业务逻辑可能包括&#xff1a;生成订单、扣减库存、使用优惠券、增加积分、通知商家用户下单、发短信通知等等。在业务发展初期这些逻辑可能放在一起…

【23种设计模式】创建型模式详细介绍

前言 本文为 【23种设计模式】创建型模式详细介绍 相关内容介绍&#xff0c;下边具体将对单例模式&#xff0c;工厂方法模式&#xff0c;抽象工厂模式&#xff0c;建造者模式&#xff0c;原型模式&#xff0c;具体包括它们的特点与实现等进行详尽介绍~ &#x1f4cc;博主主页&…

计算机组成原理(一)

1.了解计算机硬件的发展和软件的发展历程&#xff1b; 硬件&#xff1a;   电子管时代&#xff08;1946-1959&#xff09;&#xff1a;电子管、声汞延迟线、磁鼓   晶体管时代&#xff08;1959-1964&#xff09;&#xff1a;晶体管、磁芯   中、小规模集成电路时代&#…

OpenStack云平台搭建(1) | 基础环境准备

目录 一、环境准备 1.1、关闭selinxu 1.2、关闭防火墙 1.3、修改主机名 1.4、配置时间同步服务器 1.5、配置域名 二、安装OpenStack库 2.1、启用OpenStack仓库的包 2.2、安装python-openstackclient 2.3、controller安装数据库 2.4、安装消息队列 2.5、配置缓存 2.…

Linux驱动开发基础__中断的线程化处理

目录 1 引入 2 内核机制 2.1 调用 request_threaded_irq 后内核的数据结构 2.2 request_threaded_irq 2.3 中断的执行过程 1 引入 复杂、耗时的事情&#xff0c;尽量使用内核线程来处理。工作队列用起来挺简单&#xff0c;但是它有一个缺点&#xff1a;工作队列中有多个 …

【Java 面试合集】HashMap中为什么要使用红黑树

HashMap中为什么要使用红黑树1. 概述 从源码的结构方面讲述下为什么HashMap要使用红黑树。那没有红黑树的时候&#xff0c;底层是基于什么逻辑进行存储的。 2. 底层结构 如果忽略红黑树的话&#xff0c;HashMap底层的数据存储结构如下&#xff1a; 总体而言就是数组 链表的形…

Vscode使用

我是四五年的webstorm忠粉&#xff0c;一直觉得它是世界上最好用、强大、方便的编辑器。 为了它深谙各种破解方法&#xff0c;突然有一天我知道的几种方法都不奏效了。破解的实在太累了&#xff0c;算了&#xff0c;尝试尝试不同的工具吧。 含泪挥别webstrom&#xff0c;捏着…

JDBC编程复习

文章目录JDBC1.概念2.原理3. 如何使用JDBC编程1. 下载mysql的jdbc驱动2. 项目中引入驱动4. JDBC使用1. 和数据库建立连接2.获取连接3. Statement对象4. 释放资源JDBC 1.概念 JDBC,即Java Database Connectivity&#xff0c;java数据库连接。是Java提供的API用来执行SQL语句&a…

SWPU新生赛WriteUp

一个线上赛&#xff0c;这个NSSCTF最爽的就是没有靶机操作的一分钟冷却&#xff0c;10.11比赛结束&#xff0c;但是我还要看看工控&#xff0c;所以不打这个比赛了&#xff0c;先把wp写了&#xff0c;pwn入门真TM艰难 WEB 前面送分题&#xff0c;中间的也是基础题&#xff0c;…

SQL概述及数据定义

文章目录一、SQL概述1.简介2.特点3.组成4.SQL分类5.书写规范二、数据定义1.模式的定义与删除①定义模式②删除模式2.基本表的定义、删除与修改①定义基本表②数据类型③模式与表④修改基本表⑤删除基本表3.索引的建立与删除①建立索引②删除索引一、SQL概述 1.简介 SQL (Stru…

使用IDA查看汇编代码上下文去辅助排查C++软件异常问题

目录 1、概述 2、汇编指令能最直接反映异常崩溃的原因 2.1、查看异常Code码及对应的异常类型 2.2、查看发生崩溃的那条汇编指令 3、阅读汇编代码上下文需要掌握一定的基础汇编知识 4、Windbg中显示的函数调用堆栈中的C代码行号&#xff0c;和最新的代码对不上了 5、Wind…

openGL学习之GLFW和GLAD的下载和编译

背景:为什么使用GLFW和GLADOPenGL环境 目前主流的桌面平台是GLFW和GLAD之前使用的GLUT和Free GLUT已经基本淘汰了&#xff0c;所以记录一下如何下载GLFW和GLAD并且编译.GLFW下载:An OpenGL library | GLFW复制到你想存放的位置,我这里就存放到C盘Libaray文件夹下了,这里是我存放…

算法训练营 day37 贪心算法 K次取反后最大化的数组和 加油站 分发糖果

算法训练营 day37 贪心算法 K次取反后最大化的数组和 加油站 分发糖果 K次取反后最大化的数组和 1005. K 次取反后最大化的数组和 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标…

Eclipse 版本升级记录

前言 Eclipse 不是不能在线升级&#xff0c;至少没有找对方法&#xff0c;下面就让我来一步一步带你学会它、使用它吧! 一、概念 Eclipse主要分为两个概念&#xff0c;一个是在线升级 Eclipse 新版本&#xff0c;另一个是在线升级 Eclipse 插件&#xff0c;这两个是有很大区…

【记录】ChatGPT使用记录

文章目录2023年02月08日数学哲学Java其他2023年02月09日ChatGPT网络根据对话的日期、问题的类型进行整理 2023年02月08日 数学 感想&#xff1a;数学应该没啥问题&#xff0c;感觉只要自然语言没理解错了&#xff0c;剩下就不是事 积分 代数 哲学 哲学问题的回答就属于模棱…

JetpackCompose从入门到实战学习笔记7—Dialog的简单使用

JetpackCompose从入门到实战学习笔记7—Dialog的简单使用 1.Dialog对话框 Dialog的参数如下: Composable fun Dialog(onDismissRequest: (() -> Unit)?, //关闭对话框的回调properties: DialogProperties! DialogProperties(), //自定义对话框的属性content: ( Compose…