当前位置: 首页 > news >正文

【学习笔记05】C++11新特性学习总结(下)

📝 说明:本文为C++学习笔记,AI辅助系统整理
📅 整理时间:2025年9-10月
🎯 目的:系统梳理C++11核心特性,建立完整知识体系
💡 适用场景:面试复习、技术查阅


📚 本文内容

  1. nullptr(空指针)
  2. enum class(强类型枚举)
  3. delete和default关键字
  4. using别名

本篇整理的知识点(下半部分)

下半部分整理了剩余4个C++11特性:

  1. nullptr(空指针)
  2. enum class(强类型枚举)
  3. delete和default关键字
  4. using别名

知识点5:nullptr

为什么需要nullptr?

NULL的问题

void func(int x) { cout << "func(int): " << x << endl;
}void func(int* p) { cout << "func(int*): " << p << endl;
}int main() {func(NULL);     // 调用func(int)!❌ 有歧义func(nullptr);  // 调用func(int*)  ✅ 明确return 0;
}

问题原因

  • NULL本质是0(void*)0
  • 编译器会优先匹配func(int)
  • 导致重载函数调用歧义

nullptr的特点

核心特点

// nullptr是真正的空指针类型
int* p1 = nullptr;   // OK
int* p2 = NULL;      // OK,但是旧写法// nullptr不能转换为int
int x = nullptr;     // ❌ 编译错误
int y = NULL;        // ✅ OK(NULL是0)// nullptr可以转换为任何指针类型
char* cp = nullptr;
void* vp = nullptr;

我的理解:nullptr是C++11专门为空指针设计的关键字,比NULL更安全、更明确。

nullptr使用对比图

空指针表示
NULL旧方案
nullptr新方案
本质是0
重载函数歧义
可以隐式转int
真正的空指针类型
重载函数明确
不能转int

知识点6:enum class

传统enum的问题

典型示例

// 传统enum(有问题)
enum Color { RED, GREEN, BLUE };
enum Status { RED, OK };  // ❌ 编译错误!RED重复定义// 枚举值会污染外部作用域
int x = RED;  // OK,但容易混淆

问题

  1. 枚举值会污染外部作用域
  2. 不同枚举的值可能重名冲突
  3. 可以隐式转换为int

enum class的解决方案

典型示例

// enum class(安全)
enum class Color { Red, Green, Blue };
enum class Status { Red, Ok };  // ✅ OK,不冲突// 必须用作用域限定符
Color c = Color::Red;
Status s = Status::Red;// 不能隐式转int
int x = Color::Red;  // ❌ 编译错误
int y = static_cast<int>(Color::Red);  // ✅ 显式转换

enum class特点对比

特性enumenum class
作用域污染✅ 会污染❌ 不会
名字冲突✅ 可能冲突❌ 不会冲突
隐式转int✅ 可以❌ 不能
类型安全❌ 较弱✅ 强类型

我的理解:enum class更安全,防止命名冲突,是C++11推荐的写法。


知识点7:delete和default

delete禁止函数

示例:禁止拷贝

class NoCopy {
public:NoCopy() = default;  // 默认构造// 禁止拷贝NoCopy(const NoCopy&) = delete;NoCopy& operator=(const NoCopy&) = delete;
};NoCopy obj1;
NoCopy obj2 = obj1;  // ❌ 编译错误:拷贝构造被删除

示例:禁止特定参数

class OnlyInt {
public:void process(int x) { cout << "处理int: " << x << endl;}// 禁止double调用void process(double) = delete;
};OnlyInt obj;
obj.process(42);    // ✅ OK
obj.process(3.14);  // ❌ 编译错误:函数被删除

default使用默认实现

典型示例

class MyClass {
public:MyClass() = default;   // 使用编译器生成的默认构造~MyClass() = default;  // 使用编译器生成的析构MyClass(const MyClass&) = default;  // 默认拷贝构造MyClass& operator=(const MyClass&) = default;  // 默认拷贝赋值
};

Rule of 0/3/5

核心规则

  • Rule of 0:如果不需要管理资源,全部用= default
  • Rule of 3:如果定义了析构/拷贝构造/拷贝赋值,就要三个都定义
  • Rule of 5:C++11加上移动构造和移动赋值,一共5个

推荐策略

// ✅ Rule of 0:让编译器生成
class Simple {
public:Simple() = default;~Simple() = default;Simple(const Simple&) = default;Simple& operator=(const Simple&) = default;
};// ✅ Rule of 5:自己管理资源
class Resource {
public:~Resource() { delete[] data; }Resource(const Resource&) { /* 深拷贝 */ }Resource& operator=(const Resource&) { /* 拷贝赋值 */ }Resource(Resource&&) noexcept { /* 移动构造 */ }Resource& operator=(Resource&&) noexcept { /* 移动赋值 */ }
private:int* data;
};

学习中的疑问6:构造函数可以多态吗?

疑问:构造函数可以是虚函数吗?可以多态吗?

解答

  • 不能是虚函数:构造时虚函数表还未完全建立
  • 可以重载:不同参数的构造函数
  • 推荐策略:能用= default就用,需要特殊逻辑才自定义

例子

class Base {
public:Base() = default;          // 默认构造Base(int x) { }            // 重载构造virtual ~Base() { }        // 虚析构(可以)
};

知识点8:using别名

using vs typedef

语法对比

// typedef(旧)
typedef std::vector<int> IntVec;
typedef int (*FuncPtr)(int, int);  // 函数指针(难读)// using(新,推荐)
using IntVec = std::vector<int>;
using FuncPtr = int (*)(int, int);  // 更直观

using的模板别名

重要优势:typedef不支持模板别名,using可以!

// ✅ using支持模板
template<typename T>
using Vec = std::vector<T>;Vec<int> v1;     // std::vector<int>
Vec<string> v2;  // std::vector<string>// ❌ typedef做不到
// typedef std::vector<T> Vec<T>;  // 编译错误

实用的别名

典型示例

// 简化智能指针
template<typename T>
using SharedPtr = std::shared_ptr<T>;template<typename T>
using UniquePtr = std::unique_ptr<T>;// 简化容器
template<typename T>
using Vector = std::vector<T>;template<typename K, typename V>
using HashMap = std::unordered_map<K, V>;// 函数类型别名
using UpdateFunction = std::function<void(float)>;
using EventCallback = std::function<bool(const Event&)>;

我的理解:using比typedef语法更清晰,而且支持模板,是现代C++的标准写法。

using语法对比图

类型别名
typedef旧方案
using新方案
从右往左读
不支持模板
语法复杂
从左往右读
支持模板别名
语法清晰

学习中的疑问7:std::function和bind

疑问:std::function是什么?bind又是什么?

解答

std::function

存储可调用对象的通用容器:

#include <functional>// 存储普通函数
int add(int a, int b) { return a + b; }
std::function<int(int, int)> f1 = add;// 存储lambda
std::function<int(int, int)> f2 = [](int a, int b) { return a + b; };// 存储成员函数
class Calculator {
public:int multiply(int a, int b) { return a * b; }
};
Calculator calc;
std::function<int(int, int)> f3 = std::bind(&Calculator::multiply, &calc, std::placeholders::_1, std::placeholders::_2);

std::bind(现在少用)

绑定函数参数:

auto add_five = std::bind(add, std::placeholders::_1, 5);
int result = add_five(10);  // 等于add(10, 5) = 15

建议:现代C++推荐用lambda代替bind,更清晰。


学习收获(完整课时04)

上半部分收获:

  1. auto简化代码,decltype保留完整类型
  2. 列表初始化更安全,防止窄化转换
  3. 移动语义避免深拷贝,性能提升明显
  4. lambda配合STL算法,代码更简洁

下半部分收获:

  1. nullptr比NULL更安全,避免重载歧义
  2. enum class强类型,防止命名冲突
  3. delete禁止函数,default使用默认实现
  4. using别名比typedef更清晰,支持模板

总体感受:

C++11这些新特性让代码更安全、更简洁性能更好,是现代C++的基础。特别是移动语义和lambda表达式,对性能提升很明显。


课时04对应的面试题

Q1: 什么是C++中的auto和decltype?

A: auto让编译器自动推导变量类型,会丢失const和引用;decltype保留完整类型信息,主要用于模板编程。

Q2: 什么是C++的移动语义和完美转发?

A: 移动语义通过右值引用(&&)和移动构造函数,实现资源转移而不是拷贝,避免深拷贝开销。std::move将左值转为右值引用。

Q3: C++中move有什么作用?

A: std::move是类型转换函数,将左值强制转换为右值引用,启用移动语义。它本身不移动任何东西,只是类型转换。

Q4: C++的function、bind、lambda都在什么场景下会用到?

A:

  • lambda:STL算法谓词、短小回调、局部函数
  • function:存储不同类型可调用对象、回调接口
  • bind:参数绑定(现在推荐用lambda代替)

Q5: C++中为什么要使用nullptr而不是NULL?

A: nullptr是真正的空指针类型,避免重载函数调用歧义。NULL本质是0,可能导致func(int)func(int*)重载时选择错误。

Q6: C++中enum和enum class的区别?

A:

  • enum:枚举值污染外部作用域,可能命名冲突,隐式转int
  • enum class:强类型枚举,不污染作用域,必须用::访问,不能隐式转int

💡 下一步:明天学习课时05(内存管理与智能指针),掌握unique_ptr、shared_ptr、weak_ptr的使用。


📝 本篇整理完成 - C++11新特性知识体系(下)

http://www.dtcms.com/a/453192.html

相关文章:

  • RNN、LSTM与GRU模型
  • 基于华为云IOT设计的粮仓环境监测系统_303
  • 天津做网站企业保险公司网站策划
  • Linux-> TCP 编程2
  • 视频批量混剪、批量拼接,维多快剪-批量创作插件使用说明
  • JAVA算法练习题day30
  • 网站怎么做平台长沙官网制作
  • 做网站分前台后端吗怎样做一个网站平台
  • C++:异常处理与智能指针实战指南
  • 做芯片外贸生意上哪个网站深圳高端做网站公司
  • AutoCoder Nano 是一款轻量级的编码助手, 利用大型语言模型(LLMs)帮助开发者编写, 理解和修改代码。
  • Easyx使用(对弈类小作品)
  • 网站设计东莞wordpress 评论加星
  • AI(学习笔记第十课) 使用langchain的AI tool
  • 算法基础 典型题 堆
  • UVa 463 Polynomial Factorization
  • 老题新解|十进制转二进制
  • 数字信号处理 第八章(多采样率数字信号处理)
  • 网站制作农业免费封面设计在线制作生成
  • 多线程:三大集合类
  • html css js网页制作成品——化妆品html+css+js (7页)附源码
  • OpenAI战略转型深度解析:从模型提供商到全栈生态构建者的野望
  • 怎么做网站自动采集数据hao123设为主页官网下载
  • 重庆孝爱之家网站建设网站单页设计
  • 13、Linux 基本权限
  • k8s-ingress控制器
  • 【AI】深入 LangChain 生态:核心包架构解析
  • CodeBuddy Code + 腾讯混元打造“AI识菜通“
  • 记录踩过的坑-金蝶云·苍穹平台-杂七杂八
  • 【嵌入式原理系列-第11篇】半导体电子传输与PN结工作原理浅析