C++11新特性总结

前言:目前C++23版本已问世,但尚未普及,只在前沿技术验证应用居多。我们平时项目开发中仍然以主流的C++11为主,C++11可以说是现代C++的"分水岭",引入了许多新特性,大大提高了编程效率和代码性能。本文就C++11的新特性做一些分析与总结。

目录

一、核心语法升级

[1.1 自动类型推导(auto)](#1.1 自动类型推导(auto))

[1.2 范围for循环](#1.2 范围for循环)

[1.3 强类型枚举(enum class)](#1.3 强类型枚举(enum class))

[1.4 nullptr空指针常量](#1.4 nullptr空指针常量)

二、面向对象与内存管理

[2.1 智能指针](#2.1 智能指针)

[2.2 右值引用与移动语义](#2.2 右值引用与移动语义)

三、函数式编程与泛型增强

[3.1 Lamda表达式](#3.1 Lamda表达式)

[3.2 constexpr常量表达式](#3.2 constexpr常量表达式)


一、核心语法升级

1.1 自动类型推导(auto)

编译器能够根据右侧表达式自动推导变量类型,避免冗长的类型名书写,尤其适配 STL 容器迭代器、模板类型等场景。

示例:

cpp 复制代码
#include <iostream>
#include <vector>
#include <map>

int main() {
    // 基础类型推导
    auto num = 10;          // 推导为int
    auto pi = 3.14159;      // 推导为double
    auto str = "hello";     // 推导为const char*

    // STL容器迭代器(最常用场景)
    std::map<std::string, int> score_map = {{"math", 90}, {"chinese", 85}};
    // C++11之前: std::map<std::string, int>::iterator it = score_map.begin();
    auto it = score_map.begin(); // 简化了迭代器声明
    std::cout << it->first << ": " << it->second << std::endl;

    return 0;
}

1.2 范围for循环

替代传统的迭代器遍历,直接遍历容器 / 数组的每个元素,代码更简洁易读。

示例:

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    // 只读遍历
    for (auto num : nums) {
        std::cout << num << " "; // 输出1 2 3 4 5
    }
    std::cout << std::endl;

    // 修改元素(加&引用)
    for (auto& num : nums) {
        num *= 2; // 每个元素乘2
    }

    // 再次遍历验证
    for (const auto& num : nums) { // const&避免拷贝,提升效率
        std::cout << num << " "; // 输出2 4 6 8 10
    }

    return 0;
}

1.3 强类型枚举(enum class)

解决传统枚举的 "作用域污染""隐式类型转换" 问题,枚举值是强类型、作用域隔离。

示例:

cpp 复制代码
#include <iostream>

// 传统枚举:作用域全局,易冲突,可隐式转int
enum Color { Red, Green, Blue };

// C++11强类型枚举:作用域隔离,强类型
enum class Direction { Left, Right, Up, Down };

int main() {
    // 传统枚举:可直接用Red,且能转int
    Color c = Red;
    std::cout << c << std::endl; // 输出0

    // 强类型枚举:必须加作用域,不可隐式转int
    Direction d = Direction::Left;
    // std::cout << d << std::endl; // 编译报错:无重载的<<运算符
    // 如需输出,需手动重载运算符

    return 0;
}

1.4 nullptr空指针常量

解决NULL( 本质是0)的类型歧义问题,nullptr 是专属的空指针类型(std::nullptr_t),类型更安全。

示例:

cpp 复制代码
#include <iostream>

void func(int) {
    std::cout << "调用int版本" << std::endl;
}

void func(char*) {
    std::cout << "调用char*版本" << std::endl;
}

int main() {
    // C++98: NULL会匹配int版本(因为NULL是0),不符合预期
    func(NULL);     // 输出"调用int版本"
    
    // C++11: nullptr精准匹配指针版本
    func(nullptr);  // 输出"调用char*版本"

    return 0;
}

二、面向对象与内存管理

2.1 智能指针

借鉴类的构造析构原理,将指针封装成类的形式,自动管理动态内存,彻底解决内存泄漏问题(RAII 机制),替代裸指针。智能指针详细解读可参考:C++智能指针 解读_cpp 智能指针-CSDN博客

示例:

cpp 复制代码
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }
    void show() { std::cout << "MyClass::show()" << std::endl; }
};

int main() {
    // 1. unique_ptr:独占所有权,不可拷贝,可移动
    std::unique_ptr<MyClass> uptr(new MyClass());
    uptr->show();
    // std::unique_ptr<MyClass> uptr2 = uptr; // 编译报错:禁止拷贝
    std::unique_ptr<MyClass> uptr2 = std::move(uptr); // 移动语义,uptr变为空

    // 2. shared_ptr:共享所有权,引用计数
    std::shared_ptr<MyClass> sptr = std::make_shared<MyClass>(); // 推荐make_shared(更高效)
    std::shared_ptr<MyClass> sptr2 = sptr; // 引用计数+1
    std::cout << "引用计数:" << sptr.use_count() << std::endl; // 输出2

    // 3. weak_ptr:弱引用,不增加引用计数,解决shared_ptr循环引用问题
    std::weak_ptr<MyClass> wptr = sptr;
    if (auto ptr = wptr.lock()) { // 检查指针是否有效
        ptr->show();
    }

    return 0; // 智能指针自动析构,调用~MyClass()
}

2.2 右值引用与移动语义

右值引用是移动语义的基础,移动语义是为了避免深拷贝,直接 "转移" 临时对象的资源,大大提升效率。详细解读可参考:C++ 右值引用与移动语义-CSDN博客

三、函数式编程与泛型增强

3.1 Lamda表达式

定义临时的匿名函数,无需单独声明函数,适配std 算法(如std::sort )等。Lamda表达式详细解读可参考:C++ Lambda表达式-CSDN博客

示例:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5, 9};

    // 1. 排序:用Lambda自定义排序规则(降序)
    std::sort(nums.begin(), nums.end(), [](int a, int b) {
        return a > b; // 降序排序
    });

    // 2. 遍历:for_each结合Lambda
    std::for_each(nums.begin(), nums.end(), [](int num) {
        std::cout << num << " "; // 输出9 5 4 3 1 1
    });
    std::cout << std::endl;

    return 0;
}

3.2 constexpr常量表达式

使得变量 / 函数在编译期就可以确定其值或结果,而非运行期,提升程序执行效率。

示例:

cpp 复制代码
#include <iostream>

// constexpr函数:编译期计算
constexpr int square(int x) {
    return x * x;
}

int main() {
    // constexpr变量:编译期确定值
    constexpr int max_num = 100;
    constexpr int s = square(6); // 编译期计算6*6=36

    std::cout << s << std::endl; // 输出36
    return 0;
}
相关推荐
Vect__13 小时前
基于线程池从零实现TCP计算器网络服务
c++·网络协议·tcp/ip
草履虫建模16 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq18 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq19 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
学嵌入式的小杨同学19 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
Re.不晚19 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq19 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
精彩极了吧20 小时前
C语言基本语法-自定义类型:结构体&联合体&枚举
c语言·开发语言·枚举·结构体·内存对齐·位段·联合
(❁´◡`❁)Jimmy(❁´◡`❁)20 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi21 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划