73 CPP11新标准

一、long long类型

新增了类型long long和unsigned long long,以支持64位(或更宽)的整型。

在VS中,int和long都是4字节,long long是8字节。

在Linux中,int是4字节,long和long long是8字节。

二、char16_t和char32_t类型

新增了类型char16_t和char32_t,以支持16位和32位的字符。

意义不大,好像没什么人用,连demo程序都找不到。

三、原始字面量

在《45、C++11的原始字面量》中有详细介绍。

四、统一的初始化(列表)

C++11丰富了大括号的使用范围,用大括号括起来的列表(统一的初始化列表)可以用于所有内置类型和用户自定义类型。使用统一的初始化列表时,可以添加等号(=),也可以不添加:

int x={5};

double y{2.75};

short quar[5]{4,5,2,76,1};

统一的初始化列表也可以用于new表达式中:

int *ar=new int[4]{2,4,6,7};

创建对象时,也可以使用大括号(而不是圆括号)来调用构造函数:

class Girl

{

private:

    int m_bh;

    string m_name;

public:

    Girl(int bh,string name) : m_bh(bh),m_name(name) {}

};

Girl g1(3, "西施");    // C++98的风格。

Girl g2={5, "冰冰"};  // C++11的风格。

Girl g3{8, "幂幂"};    // C++11的风格。

STL容器提供了将initializer_list模板类作为参数的构造函数:

vector v1(10);   // 把v1初始化为10个元素。

vector v2{10};   // 把v2初始化为1个元素,这个元素的值是10。

vector v2{3,5,8};   // 把v3初始化为3个元素,值分别是3、5、8。

头文件提供了对模板类initializer_list的支持,这个类包含成员函数begin()和end()。除了用于构造函数外,还可以将initializer_list用于常规函数的参数:

#include

#include

double sum(std::initializer_list il)

{

    double total = 0;

    for (auto it = il.begin(); it != il.end(); it++)

        total = total + *it;

    return total;

}

int main()

{

    // double total = sum(  3.14, 5.20, 8  );    // 错误,如果没有大括号,这是三个参数。

    double total = sum({ 3.14, 5.20, 8 });        // 正确,有大括号,这是一个参数。

    std::cout

}

五、自动推导类型auto

在《140、自动推导类型auto》中有详细介绍。

六、decltype关键字 

在《146、函数模板高级》中有详细介绍。

七、函数后置返回类型

在《146、函数模板高级》中有详细介绍。

八、模板的别名

九、空指针nullptr

空指针是不会指向有效数据的指针。以前,C/C++用0表示空指针,这带来了一些问题,这样的话0既可以表示指针常量,又可以表示整型常量。

C++11新增了关键字nullptr,用于表示空指针;它是指针类型,不是整型类型。

为了向后兼容,C++11仍允许用0来表示空指针,因此表达式nullptr==0为true。

使用nullptr提供了更高的类型安全。例如,可以将0传递给形参为int的函数,但是,如果将nullptr传递给这样的函数,编译器将视为错误。

因此,出于清晰和安全考虑,请使用nullptr。

十、智能指针 

在《193、智能指针unique_ptr》至《196、智能指针weak_ptr》中有详细介绍。

十一、异常规范方面的修改

在《209、C++异常》中有详细介绍。

十二、强类型枚举(枚举类)

传统的C++枚举提供了一种创建常量的方式,但类型检查比较低级。还有,如果在同一作用域内定义的两个枚举,它们的成员不能同名。

针对枚举的缺陷,C++11 标准引入了枚举类,又称强类型枚举。

声明强类型枚举非常简单,只需要在enum后加上关键字 class。

例如∶

enum e1{ red, green };

enum class e2 { red, green, blue };

enum class e3 { red, green, blue, yellow };

使用强类型枚举时,要在枚举成员名前面加枚举名和::,以免发生名称冲突,如:e2::red,e3::blue

强类型枚举默认的类型为int,也可以显式地指定类型,具体做法是在枚举名后面加上:type,type可以是除wchar_t以外的任何整型。

例如:

enum class e2:char { red, green, blue };

十三、explicit关键字

C++支持对象自动转换,但是,自动类型转换可能导致意外。为了解决这种问题,C++11引入了explicit关键字,用于关闭自动转换的特性。

在《121、自动类型转换》中有详细介绍。

十四、类内成员初始化

在类的定义中初始化成员变量。

class Girl

{

private:

    int m_bh=20;                 // 年龄。

    string m_name="美女";        // 姓名。

    char m_xb = 'X';              // 性别。

public:

    Girl(int bh, string name) : m_bh(bh), m_name(name) {}

};

十五、基于范围的for循环

在《184、基于范围的for循环》中有详细介绍。

十六、新的STL容器

1)array(静态数组)

array的大小是固定的,不像其它的模板类,但array有begin()和end()成员函数,程序员可以array对象使用STL算法。

2)forward_list(单向链表)

3)unordered_map、unordered_multimap、unordered_set、unordered_multiset(哈希表)

十七、新的STL方法(成员函数)

1)C++11新增了的方法cbegin()、cend()、crbegin()、crend(),这些方法将元素视为const。

2)iterator emplace (iterator pos, …);  // 在指定位置插入一个元素,…用于构造元素,返回指向插入元素的迭代器。

3)更重要的是,除了传统的拷贝构造函数和赋值函数,C++11新增了移动构造函数和移动赋值函数。

十八、摒弃export

C++98新增了export关键字,C++11不再使用,但仍保留它作为关键字,供以后使用。

十九、嵌套模板的尖括号

为了避免与运算符>>混淆,C++要求在声明嵌套模板时使用空格将尖括号分开:

vector > v1;      // 两个>之间必须加空格。

C++11不再这样要求:

vector> v2;       // 两个>之间不必加空格。

二十、final关键字

final关键字用于限制某个类不能被继承,或者某个虚函数不能被重写。

final关键字放在类名或虚函数名的后面。

示例:

class AA

{

public:

    virtual void test()

    {

        cout

    }

};

class BB : public AA

{

public:

    void test() final    // 如果有其它类继承BB,test()方法将不允许重写。

    {

        cout

    }

};

class CC : public BB

{

public:

    void test()  // 错误,BB类中的test()后面有final,不允许重写。

    {

        cout

    }

};

二十一、override关键字

在派生类中,把override放在成员函数的后面,表示重写基类的虚函数,提高代码的可读性。

在派生类中,如果某成员函数不是重写基类的虚函数,随意的加上override关键字,编译器会报错。

示例:

class AA

{

public:

    virtual void test()

    {

        cout

    }

};

class BB : public AA

{

public:

    void test() override

    {

        cout

    }

};

二十二、数值类型和字符串之间的转换

传统方法用sprintf()和snprintf()函数把数值转换为char*字符串;用atoi()、atol()、atof()把char*字符串转换为数值。

C++11提供了新的方法,在数值类型和string字符串之间转换。

1、数值转换为字符串

使用to_string()函数可以将各种数值类型转换为string字符串类型,这是一个重载函数,在头文件 中声明,函数原型如下:

string to_string (int val);

string to_string (long val);

string to_string (long long val);

string to_string (unsigned val);

string to_string (unsigned long val);

string to_string (unsigned long long val);

string to_string (float val);

string to_string (double val);

string to_string (long double val);

2、字符转换为串数值

在C++中,数值类型包括整型和浮点型,针对于不同的数值类型提供了不同的函数在头文件 中声明,函数原型如下:

int                 stoi( const string& str, size_t* pos = nullptr, int base = 10 );

long               stol( const string& str, size_t* pos = nullptr, int base = 10 );

long long          stoll( const string& str, size_t* pos = nullptr, int base = 10 );

unsigned long      stoul( const string& str, size_t* pos = nullptr, int base = 10 );

unsigned long long stoull( const string& str, size_t* pos = nullptr, int base = 10 );

float               stof( const string& str, size_t* pos = nullptr );

double             stod( const string& str, size_t* pos = nullptr );

long double        stold( const string& str, size_t* pos = nullptr );

形参说明:

str:需要要转换的string字符串。

pos:传出参数,存放从哪个字符开始无法继续解析的位置,例如:123a45, 传出的位置将为3。

base:若base为0,则自动检测数值进制:若前缀为0,则为八进制,若前缀为0x或0X,则为十六进制,否则为十进制。

注意:string字符串转换为数值的函数可能会抛出异常,在《209、C++异常》中有详细介绍。

示例:

string str="123a45";

size_t pos;

int val = stoi(str, &pos, 10);

cout

cout

二十三、静态断言static_assert

在《210、C++断言》中有详细介绍。

二十四、常量表达式constexpr关键字

const关键字从功能上来说有双重语义:只读变量和修饰常量。

示例:

void func(const int len1)

{

    // len1是只读变量,不是常量。

    int array1[len1]={0};        // VS会报错,Linux平台的数组长度支持变量,不会报错。

    const int len2 = 8;

    int array2[len2]={0};      // 正确,len2是常量。

}

C++11标准为了解决const关键字的双重语义问题,保留了const表示“只读”的语义,而将“常量”的语义划分给了新添加的constexpr关键字。

所以,C++11 标准中,建议将const和constexpr的功能区分开,表达“只读”语义的场景用const,表达“常量”语义的场景用constexpr。

二十五、默认函数控制=default与=delete

在C++中自定义的类,编译器会默认生成一些成员函数:

l 无参构造函数

l 拷贝构造函数

l 拷贝赋值函数

l 移动构造函数

l 移动赋值函数

l 析构函数

=default表示启用默认函数。

=delete表示禁用默认函数。

示例:

#include

using namespace std;

class Girl

{

private:

    int m_bh = 20;                  // 年龄。

    string m_name = "美女";  // 姓名。

    char m_xb = 'X';               // 性别。

public:

    Girl() = default;                          // 启用默认构造函数。

    Girl(int bh, string name) : m_bh(bh), m_name(name) {}

    Girl(const Girl& g) = delete;      // 删除拷贝构造函数。

    void show() { cout

};

int main()

{

    Girl g1;

    g1.show();

    // Girl g2 = g1;            // 错误,拷贝构造函数已删除。

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值