C++11新标准

一、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位的字符。

三、原始字面量

原始字面量(值)可以直接表示字符串的实际含义,不需要转义和连接。

语法:R"(字符串的内容)"

           R"xxx(字符串的内容)xxx"

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

int main()
{
    // 使用转义的方法
    string path = "C:\\Program Files\\Microsoft OneDrive\\tail\\nation";
    cout << "path is " << path << endl;

    // 使用C++11原始字面量
    string path1 = R"abcd(C:\Program Files\Microsoft OneDrive\tail\nation)abcd";
    cout << "path1 is " << path1 << endl;

}

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

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<int> v1(10);   // 把v1初始化为10个元素。

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

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

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

#include <iostream>
#include <initializer_list>

double sum(std::initializer_list<double> 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 << "total=" << total << std::endl;
}

五、自动推导类型auto

见专栏文章

六、decltype关键字

见专栏文章,函数模板高级

七、函数后置返回类型

见专栏文章,函数模板高级

八、模板的别名

九、空指针nullptr

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

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

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

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

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

十、智能指针

见专栏文章

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

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

传统的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关键字,用于关闭自动转换的特性。

十四、类内成员初始化

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

class Girl

{

private:

    int m_age=20;                 // 年龄

    string m_name="月月鸟";       // 姓名

    char m_sex = 'XY';           // 性别

public:

    Girl(int bh, string name) : m_bh(bh), m_name(name) {}  //类内初始化

};

十五、基于范围的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<list<int> > v1;      // 两个>之间必须加空格。

C++11不再这样要求:

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

二十、final关键字

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

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

class AA
{
public:
    virtual void test()
    {
        cout << "AA class...";
    }
};

class BB : public AA
{
public:
    void test() final    // 如果有其它类继承BB,test()方法将不允许重写。
    {
        cout << "BB class...";
    }
};

class CC : public BB
{
public:
    void test()  // 错误,BB类中的test()后面有final,不允许重写。
    {
        cout << "CC class...";
    }
};

二十一、override关键字

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

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

class AA 
{
public:
    virtual void test()
    {
        cout << "AA class...";
    }
};

class BB : public AA
{
public:
    void test() override
    {
        cout << "BB class...";
    }
};

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

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

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

1、数值转换为字符串

使用to_string()函数可以将各种数值类型转换为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++中,数值类型包括整型和浮点型,针对于不同的数值类型提供了不同的函数在头文件 <string>中声明,函数原型如下:

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,则为十六进制,否则为十进制。

#include <iostream>
#include <initializer_list>
#include <string>
using namespace std;
//C++11新标准

int main()
{
	// 1.数值类型和字符串之间的转换
	string a;
	double b = 3.14;
	a = to_string(b);
	cout << a << endl << endl;

	//2.字符串转换为数值
	string aa = { "12345a66" };
	size_t pos;
	int val = stoi(aa, &pos, 10);
	cout << "string=" << aa << endl;
	cout << "val=" << val<<endl;
	cout << "pos=" << pos << endl<<endl;

}

二十三、静态断言static_assert

见专栏文章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++中自定义的类,编译器会默认生成一些成员函数:

  1. 无参构造函数
  2. 拷贝构造函数
  3. 拷贝赋值函数
  4. 移动构造函数
  5. 移动赋值函数
  6. 析构函数

=default表示启用默认函数。

=delete表示禁用默认函数。

示例:

#include <iostream>
using namespace std;

class Girl
{
private:
    int m_bh = 20;                 
    string m_name = "月月鸟";     
    char m_sex = 'XY';              
public:
    Girl() = default;                  // 启用默认构造函数。
    Girl(int bh, string name) : m_bh(bh), m_name(name) {}
    Girl(const Girl& g) = delete;      // 删除拷贝构造函数。
    void show() { cout << "bh=" << m_bh << ",m_name=" << m_name << endl; }
};

int main()
{
    Girl g1;
    g1.show();
    // Girl g2 = g1;            // 错误,拷贝构造函数已删除。
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值