c++11新特性之关键字(关于auto、nullptr)

1.auto

用途:

用于编译器自动推断出变量类型,这里列举几种比较典型的情况:


(1)自动类型推导

auto x = 10;       // x的类型是int  
auto y = 3.14;     // y的类型是double  
auto z = 'c';      // z的类型是char

(2)与迭代器一起使用:

当处理STL容器时,auto可以帮助我们自动推导迭代器的类型。

#include <vector>  
#include <iostream>  

using namespace std;
  
int main() {  
    vector<int> v = {1, 2, 3, 4, 5};  
    for (auto it = v.begin(); it != v.end(); ++it) {  
        cout << *it << ' ';  
    }  
    cout << '\n';  
/*
当你有一个迭代器 it 时,*it 就是迭代器所指向的容器元素的值。在遍历容器时,你通常会使用 it++ 来将迭代器移动到容器的下一个元素,然后使用 *it 来访问该元素的值。
*/
  
    // 使用C++11的基于范围的for循环(范围for循环)  
    for (auto elem : v) {  
        cout << elem << ' ';  
    }  
    cout << '\n';  
  
    return 0;  
}

(3)与lambda表达式一起使用:

当在lambda表达式中捕获变量时,可以使用auto来简化类型推导。

#include <iostream>  
#include <vector>  
#include <algorithm> 
using namespace std;
  
int main() {  
    vector<int> v = {1, 2, 3, 4, 5};  
  
    // 使用auto推导lambda表达式中捕获的变量的类型  
    auto is_even = [&](auto x) { return x % 2 == 0; };  
  
    for (auto i : v) {  
        if (is_even(i)) {  
            cout << i << ' ';  
        }  
    }  
    cout << '\n';  
  
    return 0;  
}  
  
// 注意:上述lambda中的auto参数仅在C++14及更高版本中可用

2.nullptr

用途:

  • 使用nullptr来初始化和比较指针。例如,int* ptr = nullptr; 使用nullptr初始化了一个指向int类型的空指针。
  • 当需要检查一个指针是否为空时,可以使用 if (ptr == nullptr) {...}
(1)类型安全
  • 在C++98/03中,空指针通常使用NULL宏来表示,这个宏通常被定义为0或((void*)0)。然而,这可能导致类型不明确的问题,因为NULL可以被隐式转换为任何指针类型。
  • nullptr的引入解决了这个问题,它具有独立的类型std::nullptr_t,只能被赋值给指针类型或传递给需要空指针的函数,从而增加了类型安全性。
(2)区分空指针和零值
  • 在C++98/03中,NULL既可以表示空指针,也可以表示整数零,这可能会导致混淆。
  • nullptr的引入使得空指针有了明确的表示,避免了这种混淆。
// C++11 之前  
int* ptr1 = NULL;  
int* ptr2 = 0;  
  
// C++11 及以后  
int* ptr3 = nullptr;
(3)与标准库的交互
  • C++标准库中的一些组件,如智能指针(unique_ptr和shared_ptr),需要一种明确的方式来表示空指针。使用nullptr可以确保这些组件正确地初始化和管理它们所拥有的资源。
(4)提高代码的可读性和可维护性
  • 使用nullptr可以使代码更加清晰,因为它明确表示了一个指针没有指向任何对象。这有助于减少由于空指针使用不当而导致的错误,并使代码更容易理解和维护。
(5)函数重载
  • 在函数重载中,nullptr的表现优于NULL或0。例如,如果有一个函数既接受整数参数又接受指针参数,并且你希望传递一个空指针参数,使用nullptr可以明确调用接受指针参数的函数版本,而使用0则会调用接受整数参数的版本。
#include <iostream>  

using namespace std;
  
// 函数重载,接受 int* 参数  
void foo(int* ptr) {  
    cout << "foo(int*): Received a pointer." << endl;  
    // 这里可以执行与 ptr 相关的操作  
}  
  
// 函数重载,接受 int 参数  
void foo(int value) {  
    cout << "foo(int): Received an integer." << endl;  
    // 这里可以执行与 value 相关的操作  
}  
  
int main() {  
    // 使用 nullptr 明确调用接受 int* 参数的 foo 函数  
    foo(nullptr); // 输出: foo(int*): Received a pointer.  
  
    // 使用 0 会导致调用接受 int 参数的 foo 函数,因为 0 可以隐式转换为 int  
    foo(0); // 输出: foo(int): Received an integer.  
  
    // 正常使用 int* 类型的指针  
    int x = 42;  
    foo(&x); // 输出: foo(int*): Received a pointer.  
  
    return 0;  
}
(6)RAII原则
  • RAII(Resource Acquisition Is Initialization)是C++中的一个重要概念,它强调资源的获取和释放应该与对象的生命周期绑定。nullptr的使用有助于实现这一原则,因为它提供了一种明确的方式来表示一个指针没有拥有任何资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值