C++八股文(四)

C++八股文(四)

1. C++11 的新特性有哪些

C++新特性主要包括包含语法改进和标准库扩充两个方面,主要包括以下11点:

  1. 语法的改进

    (1)统一的初始化方法

    (2)成员变量默认初始化

    (3)auto关键字 用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化)

    (4)decltype 求表达式的类型

    (5)智能指针 shared_ptr

    (6)空指针 nullptr(原来NULL)

    (7)基于范围的for循环

    (8)右值引用和move语义 让程序员有意识减少进行深拷贝操作

  2. 标准库扩充(往STL里新加进一些模板类,比较好用)

    (9)无序容器(哈希表) 用法和功能同map一模一样,区别在于哈希表的效率更高

    (10)正则表达式 可以认为正则表达式实质上是一个字符串,该字符串描述了一种特定模式的字符串

    (11)Lambda表达式

具体展开:

  1. 统一的初始化方法

    C++98/03 可以使用初始化列表(initializer list)进行初始化:

    int i_arr[3] = {
          1, 2, 3 };
    long l_arr[] = {
          1, 3, 2, 4 };
    struct A
    {
         
        int x;
        int y;
    } a = {
          1, 2 };
    

    但是这种初始化方式的适用性非常狭窄,只有上面提到的这两种数据类型可以使用初始化列表。在 C++11 中,初始化列表的适用性被大大增加了。它现在可以用于任何类型对象的初始化,实例如下:

    class Foo
    {
         
    public:
        Foo(int) {
         }
    private:
        Foo(const Foo &);
    };
    int main(void)
    {
         
        Foo a1(123);
        Foo a2 = 123;  //error: 'Foo::Foo(const Foo &)' is private
        Foo a3 = {
          123 };
        Foo a4 {
          123 };
        int a5 = {
          3 };
        int a6 {
          3 };
        return 0;
    }
    

    在上例中,a3、a4 使用了新的初始化方式来初始化对象,效果如同 a1 的直接初始化。a5、a6 则是基本数据类型的列表初始化方式。可以看到,它们的形式都是统一的。这里需要注意的是,a3 虽然使用了等于号,但它仍然是列表初始化,因此,私有的拷贝构造并不会影响到它。a4 和 a6 的写法,是 C++98/03 所不具备的。在 C++11 中,可以直接在变量名后面跟上初始化列表,来进行对象的初始化。

  2. 成员变量默认初始化

    好处:构建一个类的对象不需要用构造函数初始化成员变量。

    //程序实例
    #include<iostream>
    using namespace std;
    class B
    {
         
    public:
        int m = 1234; //成员变量有一个初始值
        int n;
    };
    int main()
    {
         
        B b;
        cout << b.m << endl;
        return 0;
    }
    
  3. auto关键字

    用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化)。

    //程序实例
    #include <vector>
    using namespace std;
    int main(){
         
        vector< vector<int> > v;
        vector< vector<int> >::iterator i = v.begin();
        return 0;
    }
    

    可以看出来,定义迭代器 i 的时候,类型书写比较冗长,容易出错。然而有了 auto 类型推导,我们大可不必这样,只写一个 auto 即可。

  4. decltype 求表达式的类型

    decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导。

    (1)为什么要有decltype

    ​ 因为 auto 并不适用于所有的自动类型推导场景,在某些特殊情况下 auto 用起来非常不方便,甚至压根无法使用,所以 decltype 关键字也被引入到 C++11 中。

    ​ auto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:

    auto varname = value;
    decltype(exp) varname = value;
    

    其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。

    ​ auto 根据"=“右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟”="右边的 value 没有关系。

    ​ 另外,auto 要求变量必须初始化,而 decltype 不要求。这很容易理解,auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。decltype 可以写成下面的形式:

    decltype(exp) varname;
    

    (2)代码示例

    // decltype 用法举例
    int a = 0;
    decltype(a) b = 1;  //b 被推导成了 int
    decltype(10.8) x = 5.5;  //x 被推导成了 double
    decltype(x + 100) y;  //y 被推导成了 double
    
  5. 智能指针 shared_ptr

    ​ 和 unique_ptr、weak_ptr 不同之处在于,多个 shared_ptr 智能指针可以共同使用同一块堆内存。并且,由于该类型智能指针在实现上采用的是引用计数机制,即便有一个 shared_ptr 指针放弃了堆内存的“使用权”(引用计数减 1),也不会影响其他指向同一堆内存的 shared_ptr 指针(只有引用计数为 0 时,堆内存才会被自动释放)。

    #include <iostream>
    #include <memory>
    using namespace std;
    int main()
    {
         
        //构建 2 个智能指针
        std::shared_ptr<int> p1(new int(10));
        std::shared_ptr<int> p2(p1);
        //输出 p2 指向的数据
        cout << *p2 << endl;
        p1.reset();//引用计数减 1,p1为空指针
        if (p1) {
         
            cout << "p1 不为空" << endl;
        }
        else {
         
            cout << "p1 为空" << endl;
        }
        //以上操作,并不会影响 p2
        cout << *p2 << endl;
        //判断当前和 p2 同指向的智能指针有多少个
        cout << p2.use_count() << endl;
        return 0;
    
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值