博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++11中一些新特性
阅读量:5121 次
发布时间:2019-06-13

本文共 4687 字,大约阅读时间需要 15 分钟。

1.列表初始化

1.1扩展了初始化列表(用{}括起来的列表)的使用范围

使其可用于所有的内置类型和用户自定义的类型,使用初始化列表可以加=(没区别),也可不加。例如以下用法:

int a = { 1 }; //多此一举int b{ 2 };int c{ 1 + 2 };int d{ a + b };vector
v = { 1, 2, 3, 4 };vector
vs = { "string", "vector" };int *arr = new int[]{
1, 2, 3, 4};map
mymap{ { 1, 1 }, { 2, 2 } };

1.2自定义类型的列表初始化

class Date{public:    Date(int year, int month, int day)        :_year(year)        , _month(month)        , _day(day)    {}private:    int _year;    int _month;    int _day;};int main(){    Date d1{ 2019, 6, 26 }; //标准库支持单个对象使用列表进行初始化    return 0;}

对于多个对象的列表初始化:

首先认识一个新的数据结构 initializer_list

#include 
int main(){ initializer_list
initlist{ 1, 2, 3, 4 }; auto it = initlist.begin(); for (; it != initlist.end(); ++it) { cout << *it << " "; } cout << endl; cout << initlist.size() << endl; return 0;}

initializer_list支持迭代器,size()接口

在多个对象的列表初始化时,C++11是用了initializer_list,必须包含一个带有initializer_list参数的构造函数,类似:

template 
class Vector{public: Vector(initializer_list
l) //包含一个带有initializer_list参数的构造函数 :_capacity(l.size()) , _size(0) { _arr = new T[_capacity]; for (const auto& it : l) { _arr[_size++] = it; } } size_t size() { return _size; } T& operator[](size_t i) { return *(_arr + i); }private: T *_arr; size_t _size; size_t _capacity;};int main(){ Vector
V{ 1, 2, 3, 4 }; //用{}内容构建了一个initializer_list对象 for (size_t i = 0; i < V.size(); ++i) { cout << V[i] << " "; } cout << endl; return 0;}

2.变量类型推导

2.1 auto

当变量类型写起太复杂或不知道实际类型时,例如:

int main(){    short a = 32760;    short b = 32765;    //若指定c的类型为short,则会造成数据丢失,    //使用auto,让编译器自己推演c的实际类型,就不会存在问题    auto c = a + b; //c的类型为int    unordered_map
mymap{ { 1, 1 }, { 2, 2 } }; //unordered_map
::iterator it = mymap.begin(); auto it = mymap.begin(); //使用auto可避免如上复杂的写法 return 0;}

2.2 decltype类型推导

auto在使用时必须对变量进行初始化,编译器才能推演出变量的实际类型。

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

根据类型推导定义变量:

int a = 1;int b = 2;decltype(a + b) c; //推演为int c;

推演函数返回值类型:

void *func(){    return (void *)0;}int main(){    //不带参数列表是,返回函数的类型    cout << typeid(decltype(func)).name() << endl; //void * __cdecl(void)    //带参数列表时,返回函数返回值类型    cout << typeid(decltype(func())).name() << endl; //void *    return 0;}

decltype使用RTTI(运行时类型识别),C++98也支持了RTTI,在typeid和dynamic_cast中有使用。运行时类型识别会降低程序运行效率。

3.基于范围for的循环

vector
v{ 1, 2, 3, 4 };for (auto it : v){ //...}

4.final和override

用final修饰的类不可被继承:

class A final{public:    A(int data = 1)        :_data(data)    {}    void print()    {        cout << _data << endl;    }private:    int _data;};class B : public A //不能将“final”类类型用作基类{};

用final修饰的虚函数不可被重写:

class A{public:    A(int data = 1)        :_data(data)    {}    virtual void print() final    {        cout << _data << endl;    }private:    int _data;};class B : public A{    void print() //无法重写“final”函数 "A::print"    {        //...    }};

 override关键字表示当前函数重写了基类中的虚函数:

class A{public:    A(int data = 1)        :_data(data)    {}    virtual void print()     {        cout << _data << endl;    }private:    int _data;};class B : public A{public:    virtual void print() override;};int main(){    B b;    b.print();    return 0;}

被override修饰的函数必须重写基类中该虚函数,不会继承基类中该函数的实现,以上程序链接失败,因为print函数在派生类中被override修饰,却没有具体实现。

5.委派构造函数

委派函数将构造的任务委派给目标构造函数来完成的一种类构造的方式。

class Info{public:    //目标构造函数:将构造函数体中重复的代码提出来作为一个基础版本,用于在其它构造函数中调用    Info() //被委派        :_a(1)        , _c('c')    {        Init();//一些初始化行为    }    //委派构造函数    Info(int a)        :Info() //委派    {        _a = a;    }    Info(char c)        :Info() //委派    {        _c = c;    }private:    void Init()    {        //...    }private:    int _a;    char _c;};

构造函数不能同时“委派”和使用参数列表。

6.默认函数控制

在C++中对一个空类编译器会生成一些默认成员函数,例如构造函数、拷贝构造、赋值运算符重载、析构函数、&和const&的重载、移动构造、移动拷贝构造等。如果显示的定义了,则不会生成默认的。而有时又需要一个无参的构造函数,C++11可以显示的控制是否生成默认的函数。

6.1生成默认函数

C++11中在默认函数声明或定义后加=default,表示让编译器生成该函数的默认版本(显示缺省函数)。

class A{public:    A(int a)        :_a(a)    {}    A() = default; //声明时指定生成默认版本    A& operator=(const A& a); //声明private:    int _a;};A& A::operator=(const A& a) = default; //定义时让编译器生成默认版本

6.2删除默认函数

如果想要限制某些默认函数的生成,在C++98中我们会将该函数声明为私有不实现。在C++11中我们只需在函数声明后加上=delete即可,编译器就不会生成该函数。

class A{public:    A(int a)        :_a(a)    {}    A() = default;    A& operator=(const A& a) = delete;private:    int _a;};int main(){    A a(1);    A b;    b = a; //无法引用 函数 "A::operator=(const A &a)"它是已删除的函数    return 0;}

 

转载于:https://www.cnblogs.com/dabai56/p/11088602.html

你可能感兴趣的文章
博弈论 从懵逼到入门 详解
查看>>
永远的动漫,梦想在,就有远方
查看>>
springboot No Identifier specified for entity的解决办法
查看>>
慵懒中长大的人,只会挨生活留下的耳光
查看>>
"远程桌面连接--“发生身份验证错误。要求的函数不受支持
查看>>
【BZOJ1565】 植物大战僵尸
查看>>
VALSE2019总结(4)-主题报告
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
中国烧鹅系列:利用烧鹅自动执行SD卡上的自定义程序(含视频)
查看>>
Solaris11修改主机名
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>
Flask 系列之 SQLAlchemy
查看>>
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
python常用函数
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>