【深入理解C++11】第七章 为改变思考方式而改变

7.1 指针空值 nullptr

 在C++中一般一个指针声明都是char* p = NULL;表示一个指针处于初始化状态,NULL一般是一个宏定义,定义如下:

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

此时我们如下使用就会出问题,我们想要通过func(NULL)调用一个指针类型的重载,而MSVC编译器将会调用int入参类型的fun函数重载这显然不是我们想要的。

void fun(char *c)
{
    cout << "fun char *" << endl;
}

void fun(int i)
{
    cout << "fun int " << endl;
}

//打印:fun int 
fun(NULL);

 在C++11中nullptr则是一个“指针空值类型”,在C++11中指针空值类型被命名为nullptr_t定义为,事实上,我们可以在cstddef中(或者其包含的头文件中找到如下定义):
typedef decltype(nullptr) nullptr_t;
比如在模板推导时,编译器一般都可以指出nullptrnullptr_t,另外在模板类型为T*时,我们传入nullptr则是编译失败,需要手动增加显式类型转换。

template<typename T> void g(T*t) {
    cout << typeid(T).name() << endl;
}
template<typename T> void f(T t) {
    cout << typeid(T).name() << endl;
}

    g((float*)nullptr);
    //g(nullptr);       //error
    f(nullptr);
    //打印
    //float
    //std::nullptr_t

7.2 默认函数的控制

 C++11中提供了defaultdelete来修饰默认构造、拷贝等函数。
简单的使用如下:

class ConvType
{
public:
    ConvType(int i) {};
    ConvType() = default;
    ConvType(char c) = delete;
};

void func(ConvType ct) {}

    //使用如下
    func(1);                //隐式转换
    func(ConvType());       //默认构造函数
    func('c');              //编译失败

当然如果我们想要一个对象,不能使用堆来构造对象,可以删除自定义类型的operator new操作符即可,示例如下:

class NoHeapAlloc
{
public:
    void * operator new (std::size_t) = delete;
};

    NoHeapAlloc nha;
    NoHeapAlloc *pnha = new NoHeapAlloc;    //编译失败

7.3 lambda函数

 lambda在C++11中的形式如下:

auto sum = [](int x,int y) -> int{ return x + y; };

语法定义如下:
[capture] (parameters) mutable -> return-type {statement}

  • [captrue]:捕捉列表,总是出现在lambda函数开始处。
    捕获列表描述:
    1. [var]传值捕获var。
    2. [=]捕捉父作用域所有变量,包括this。
    3. [&var]引用传递变量var。
    4. [&]引用捕捉父作用域所有变量,包括this。
    5. [this]值传递方式捕捉this指针。
  • (parameters) :参数列表,没有参数可以省略。
  • mutable:默认lambda是const类型函数,mutable可以取消常量性。
  • -> return-type:返回类型,用追踪返回类型形式声明函数返回类型。
  • {statement}:与普通函数一致。

 lambda对于C++11中最大的贡献应该是对于STL库的改变了,我们会发现使用STL算法更容易了。

比如for_each的原型:

template<class InputIt, class UnaryFunction>
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
    for (; first != last; ++first) {
        f(*first);
    }
    return f; // implicit move since C++11
}

我们结合lambda可以如下使用:

    std::vector<int> arr{6,5,3,21,1,3,54,3,6};
    //打印偶数
    for_each(arr.begin(), arr.end(), [&arr](int val)
    {
        if (val % 2 == 0)
        {
            cout << val << " ";
        }
    });

7.4 本章小结

本章主要讲解:nullptr、default、delete、lambda。

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值