【C++】C++11的类功能增强与STL变化

目录

[1. 默认成员函数的增减](#1. 默认成员函数的增减)

[2. = default 和 = delete](#2. = default 和 = delete)

[3. final与override](#3. final与override)

[4. 成员变量声明时的缺省值](#4. 成员变量声明时的缺省值)

[5. STL中的变化](#5. STL中的变化)


1. 默认成员函数的增减

C++98的类有6个默认成员函数,但真正常用的是前四个:构造、析构、拷贝构造、拷贝赋值。C++11新增了两个:移动构造 和移动赋值。

如果用户没有定义拷贝构造、拷贝赋值、析构中的任何一个,编译器就会尝试自动生成移动构造和移动赋值。对于内置类型成员,逐字节拷贝;对于自定义类型成员,优先调用其移动构造/移动赋值,没有则回退到拷贝。

这也意味着,一旦定义了析构函数(说明有资源需要管理),编译器就不会自动给你移动操作了。想要移动,需要手动写或者用= default显式声明。

如果自定义了移动构造或移动赋值,编译器不会自动生成拷贝版本。这个设计的潜台词是:当你的类需要特殊的移动逻辑时,默认的拷贝往往也不对,不如提醒你自己处理。

2. = default 和 = delete

C++11允许用= default显式要求编译器生成默认版本,用= delete明确禁止某个函数。

cpp

复制代码
class Person {
public:
    Person(const Person&) = default;   // 要默认拷贝
    Person(Person&&) = default;        // 要默认移动
    Person& operator=(const Person&) = delete;  // 禁止拷贝赋值
};

= delete可以禁掉任何函数,而不仅仅用于默认成员函数。比如防止隐式类型转换:

cpp

复制代码
void func(int);
void func(double) = delete;  // 禁止传double
func(3.14);  // 编译错误

3. final与override

这两个关键字在继承和多态中使用,C++11正式纳入标准。

  • override:显式声明当前函数是重写基类虚函数,编译器会帮你检查签名是否匹配。

  • final:阻止类被继续继承,或者阻止某个虚函数被重写。

cpp

复制代码
class Base {
public:
    virtual void print() const;
};

class Derived : public Base {
public:
    void print() const override;  // OK,覆盖
    // void print() override;     // 错误,签名不匹配,缺少const
};

class FinalClass final : public Derived { };  // 禁止再继承

这两个关键字本质是编译期的"文档 + 安保",让意图显式化,减少因签名拼写错误导致的非预期行为。实际开发中应该养成用override的习惯。

4. 成员变量声明时的缺省值

C++11允许在类定义中直接给成员变量赋予缺省值:

cpp

复制代码
class Date {
    int _year = 1970;
    int _month = 1;
    int _day = 1;
};

这些缺省值用于初始化列表。如果构造函数没有在初始化列表中显式初始化某个成员,就会用缺省值。这在一定程度上减轻了为每个构造函数重复写初始化列表的负担。

5. STL中的变化

C++11给STL做了不少升级,一部分前文已经涉及,这里做个汇总:

  • 新容器 :unordered_map、unordered_set、array、forward_list等。前两个在实际工程中使用率很高,哈希表替代手写,性能敏感场景选型时多了一个选择。

  • 移动语义支持 :所有容器都实现了移动构造和移动赋值,push_back和insert增加了右值引用版本,emplace系列接口登场。

  • initializer_list支持:所有容器都可以用花括号初始化,赋值也可以用花括号。

  • 范围for :配合begin()、end(),直接用for (auto&& elem : container)遍历。

  • 一些新接口 :如cbegin()、cend()返回const迭代器,shrink_to_fit()请求释放多余容量等,用到时查文档就行。

智能指针(unique_ptr、shared_ptr、weak_ptr)也是C++11的重磅特性,但属于内存管理范畴,更适合单独拆开细讲,这里不展开了。

C++11的改动量之大,堪称"新语言"。但它的很多设计并不是凭空而来,而是对工程实践中长期积累的痛点的系统性回应。理解这些特性产生的动机,比记语法更重要。

相关推荐
u01110267511 小时前
图片处理接口如何统一错误信息 前端提示与后端错误码设计
前端·状态模式
好想像大佬一样能够ak所有11 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111111 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS12 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b12 小时前
算法日常・每日刷题--<动态规划>14
算法
福兮说12 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
libokaifa12 小时前
把语音模型塞进手机:sherpa-onnx 在 Android 上的 ASR / TTS
前端
赛博守夜人12 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全
Joy T12 小时前
Spring AI 接入已有 Java 项目的三种架构设计
java·人工智能·springai·ai入门·chatclient·ai service·ai能力接入
deli00712 小时前
DLA 枝晶生长实测:5000 个粒子集体停摆之后,分形维数收敛到 1.70
前端