IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++面试:说下你用过的C++11新特性 -> 正文阅读

[C++知识库]C/C++面试:说下你用过的C++11新特性

类型

nullptr 和std::nullptr_t

  • C++11引入了nullptr取代0和NULL,表示指向一个不确定的值。这样可以避免“null pointer被解释为一个整数值”时的错误
void f(int);
void f(void *);

f(0);  // call f(int);
f(NULL); //call f(int),  f(void *)
f(nullptr); //call f(void *);
  • nullptr是个新关键字,它被自动转换为各种pointer类型,但是不会被转换为任何整型,它是一个std::nullptr_t的类型

除此之外,它引入了一些新类型:

  • char16_t、char32_t
  • long long 、unsigned long long

auto:自动推导变量类型

  • auto根据变量的初值自动推导其类型。因此一定要有初始化操作
auto i = 11; //ok
auto j;  //error

decltype:推导表达式类型

decltype自动推导编译器类型。这其实是typeof的特性体现。只不过原来的typeof缺乏一致性又不安全,所以引入了decltype

std::map<std::string, float> coll;
delctype(coll)::value_type elem;

应用场景:

  • 声明返回类型
  • 传递lambda类型

举例:

有时候,有一种需求,函数的返回类型取决于某个表达式对实参的处理。在C++11之前是没法处理的,因为返回式所使用的对象尚未被引入。而C++11其,可以将一个函数的返回类型转而声明于参数列之后:

template<typename  T1, typename T2>
auto add(T1 x, T2 y) ->decltype(x + y);

noexcept:声明不会抛出异常,如果内部有异常那么程序终止

  • noexcept:
    • 说明某个函数不打算或者说无法抛出异常
    • 比如下面声明了f()不打算抛出异常。如果有异常未在foo()中处理,那么程序将会终止。然后std::terminate()被调用并默认调用std::abort()
void f()noexcept;
  • 为什么要引入noexcept:

    • 运行期校验:C++只检验运行期异常而不能检验编译器异常,所以它无法保证每个异常都被处理。
    • 运行期开销:运行期检验会令编译器产生额外代码并妨碍优化
    • 无法用于泛型码中:泛型码往往无法知道哪一类异常可能被“操作template实参”的函数抛出,所以我们无法写出正确的异常明显
    • 函数大致分为两种:
      • 可能抛出异常
      • 绝对不可能抛出异常
    • noexcept刚好对应这两种情况

constexpr:常量表达式

  • 作用:

    • 常量表达式指的是在编译过程中就能确定计算结果的表达式
  • 为什么要引入常量表达式:

    • 类型1+2, 3*4这种表达式总是会产生相同的结果并且没有任何副作用。如果编译器能够在编译时就把这些表达式直接优化并植入程序运行时,将能增加程序的性能
    • 计算的时机从运行期提前到编译期,比宏定义效率更高
constexpr int sq(int i){
		return i * i;
}


float a[sq(9)];

foreach循环

for(decl : coll){
	stactememt
}

lambda表达式

强类型枚举

之前的枚举

enum {
        General,Light,Medium,Heavy
 };

 enum Type{
        General,Light,Medium,Heavy
 };

C++11之后引入的枚举

enum class Type:int{
	 Generay, 
	 Light, 
	 Medium, 
	 Heavy
};

enum class Type:char{
	 Generay, 
	 Light, 
	 Medium, 
	 Heavy
};

重点在于,在enum之后的关键字class

优点:

  • 绝不对隐式转换至int

  • 可以指定底层类型。强类型枚举默认的底层类型是int,但也可以显式的指定底层类型

  • 强作用域:强类型枚举成员的名称不会被输出到其父作用域空间。 也也导致了我们在使用类型成员的时候必须加上所属的枚举类型的名字。

  • C/C++编程:强类型枚举

初始化相关

一致性初始化

  • C++11之前, 初始化方式,乱七八糟,不同编译器的对待方式也不太一样。为此,C++引入了所谓的一致性初始化语法,也就是{}来一统江湖
int values[]{ 1,2,3,4,5,6,7,8,9 };
int* a = new int[3] { 1, 2, 0 }; //C++11 only
std::vector<char> vec{'a','b' ,'c' ,'d' ,'e' };
std::map<int, std::string>m1{ { 1,"a" },{ 2,"b" },{ 3,"c" },{ 4,"d" } };
  • 为了让用户自定义类型也可以使用{},C++11引入了class template std::initializer_list<>

class MaginFoo{
public:
    MaginFoo(std::initializer_list<int> list){
      	....
    }	
};

 MaginFoo maginFoo = {1, 2, 3, 4};

右值

右值可以说是C++11中最重要的特性了。我们必须先了解下什么是左值,什么是右值。简单来说:

  • 左值有内存实体,可以长久存在
  • 右值没有内存实体,只是临时存在,用完即销毁
  • C++11中有一个函数叫做std::move(将左值强制转换为右值),它可以将某个左值转换为右值。为什么要用std::move呢?
auto right = std::move(left);

为什么要引入右值呢?是为了实现移动语义完美转发

什么是移动语义呢?

  • 移动就是搬移,简单理解将左值所拥有的资源抢过来,然后左值就可以销毁了。
  • 在C++11之前,如果想用其他对象初始化一个同类的新对象,只能借助类的拷贝构造函数拷贝赋值函数,必须先将新对象复制一份和其他对象一模一样的数据,然后就把老的值销毁
class X{
public:
	X(const X&);  //拷贝构造函数
	X& operator=(const X&);
};
  • 而引入右值之后,就有了移动构造函数移动赋值函数,它可以将原来的值抢到新的值之上。这就少了一份拷贝操作,效率会快很多
class X{
public:
	X(const X&&);  //移动构造函数
	X& operator=(const X&&);
};

关于完美转发

模板相关

不定参数模板

  • 采用递归的方式拆解函数模板中的不定参。一定要有一个特化模板去做终止条件
  • 其中sizeof...(args)会生成实参个数
/* 递归调用的终止条件 */
void print()
{
    cout<<"The end!!!"<<endl;
}


/* 不定参函数模板的使用 采用的是递归的方式 */
template<typename T,typename ... Types>
void  print(const T &fristArg,const Types&... args)
{
    cout<<fristArg<<endl;
   // cout<<"variadic template function sizeof Usage:"<<sizeof...(args)<<endl;
    print(args...);
}


int main(int argc, char const *argv[])
{
    print("hhaah",112,333,222,999,000);
    return 0;
}


C++11新特性之不定参模板

alias template

智能指针

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-26 15:13:27  更:2022-05-26 15:13:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 18:20:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码