写点什么

c++11 基础

作者:雪芙花
  • 2022-10-20
    湖南
  • 本文字数:1846 字

    阅读完需:约 1 分钟

C++11 入门

1. C++11 简介

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

2. 列表初始化

C++98 中{}的初始化问题

在 C++98 中,标准允许使用花括号{}对数组元素进行统一的列表初始值设定。比如:


int array1[] = {1,2,3,4,5};int array2[5] = {0};
复制代码


  • 对于一些自定义的类型,却无法使用这样的初始化。比如:


vector<int> v{1,2,3,4,5};
复制代码


就无法通过编译,导致每次定义 vector 时,都需要先把 vector 定义出来,然后使用循环对其赋初始值,非常不方便。


  • C++11 扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加.

  • 多个对象想要支持列表初始化,需给该类(模板类)添加一个带有 initializer_list 类型参数的构造函数即可

  • 注意:initializer_list 是系统自定义的类模板,该类模板中主要有三个方法:begin()**、**end()迭代器以及获取区间中元素个数的方法 size() .


#include <initializer_list>template<class T>class Vector {public:// ...Vector(initializer_list<T> l): _capacity(l.size()), _size(0){_array = new T[_capacity];for(auto e : l)_array[_size++] = e;}Vector<T>& operator=(initializer_list<T> l) {delete[] _array;size_t i = 0;for (auto e : l)_array[i++] = e;return *this;}// ...private:T* _array;size_t _capacity;size_t _size;};
复制代码

3. 变量类型推导

  • 为什么需要类型推导


在定义变量时,必须先给出变量的实际类型,编译器才允许定义,但有些情况下可能不知道需要实际类型怎么给,或者类型写起来特别复杂,比如:


#include <map>#include <string>int main(){short a = 32670;short b = 32670;// c如果给成short,会造成数据丢失,如果能够让编译器根据a+b的结果推导c的实际类型,就不会存在问题short c = a + b;std::map<std::string, std::string> m{{"apple", "苹果"}, {"banana","香蕉"}};// 使用迭代器遍历容器, 迭代器类型太繁琐std::map<std::string, std::string>::iterator it = m.begin();while(it != m.end()){cout<<it->first<<" "<<it->second<<endl;++it;}return 0;}
复制代码


C++11 中,可以使用 auto 来根据变量初始化表达式类型推导变量的实际类型,可以给程序的书写提供许多方便。将程序中 c 与 it 的类型换成 auto,程序可以通过编译,而且更加简洁。

decltype 类型推导

auto 使用的前提是:必须要对 auto 声明的类型进行初始化,否则编译器无法推导出 auto 的实际类型。但有时候可能需要根据表达式运行完成之后结果的类型进行推导,因为编译期间,代码不会运行,此时 auto 也就无能为力。


template<class T1, class T2>T1 Add(const T1& left, const T2& right){return left + right;}
复制代码


  • 使用:



decltype 是根据表达式的实际类型推演出定义变量时所用的类型,比如:

  1. 推演表达式类型作为变量的定义类型

int main()
{
int a = 10;
int b = 20;
// 用decltype推演a+b的实际类型,作为定义c的类型
decltype(a+b) c;
cout<<typeid(c).name()<<endl;
return 0;
}

  1. 推演函数返回值的类型

void* GetMemory(size_t size)
{
return malloc(size);
}
int main()
{
// 如果没有带参数,推导函数的类型
cout << typeid(decltype(GetMemory)).name() << endl;
// 如果带参数列表,推导的是函数返回值的类型,注意:此处只是推演,不会执行函数
cout << typeid(decltype(GetMemory(0))).name() <<endl;
return 0;
}

4.范围 for 循环

范围 for 的本质还是迭代器,要求迭代器支持++和 ==


  • 例:


int main(){  vector<int> arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  for (auto& e : arr)  {    e *= 2;  }  for (auto e : arr)  {    cout << e << " ";  }  cout << endl;  return 0;}
复制代码

ps

想和博主一样刷优质面试和算法题嘛,快来刷题面试神器牛客吧,期待与你在牛客相见噢!

发布于: 1 小时前阅读数: 6
用户头像

雪芙花

关注

还未添加个人签名 2022-04-28 加入

还未添加个人简介

评论

发布
暂无评论
c++11基础_c_雪芙花_InfoQ写作社区