[C++11] 类中新特性的添加

news2024/11/26 14:34:13

默认的移动构造和移动赋值

在 C++11 之前,编译器会为每个类自动生成默认的构造函数、析构函数、拷贝构造函数、拷贝赋值运算符等函数,以实现对象的创建、销毁和拷贝操作。但拷贝操作会复制整个对象的数据,效率低,尤其是在处理大对象或动态分配的资源时。为了解决这一问题,C++11 引入了移动语义(Move Semantics),并提供了两个新的默认函数:移动构造函数移动赋值运算符

移动构造和移动赋值运算符的作用是通过“转移”资源来代替“复制”资源,提高效率。它们通常用于避免不必要的拷贝操作,尤其是当资源的原有所有者不再需要保留这些资源时。

生成规则

  • 若类未定义析构函数、拷贝构造函数、拷贝赋值运算符或移动构造函数,编译器会自动生成默认的移动构造和移动赋值运算符。
  • 若类包含自定义析构函数、拷贝构造函数或拷贝赋值运算符,则编译器不会自动生成移动构造和移动赋值运算符,除非显式指定 =default

移动构造函数和移动赋值的行为

  • 内置类型成员将按字节逐一拷贝。
  • 自定义类型成员会优先调用它们的移动构造函数(若存在),否则调用拷贝构造函数。

也就是说,与其他的默认函数一样,自定义类型仍然需要看本身有没有实现相应的函数。

示例代码
#include <string>
#include <utility> // 包含std::move

class Person {
public:
    Person(const char* name = "", int age = 0)
        : _name(name), _age(age) {}

// 移动构造函数自动生成,因为未定义拷贝构造或赋值函数

private:
    std::string _name;
    int _age;
};

int main() {
    Person p1("Alice", 25);
    Person p2 = std::move(p1); // 触发移动构造
    
    return 0;
}

在上述代码中,std::movep1 转换为右值引用(rvalue reference),指示编译器可以“转移”p1 的资源,而无需拷贝。p1 的数据会被移动到 p2,此操作避免了 p1 的拷贝过程。

注意

若类定义了移动构造函数或移动赋值运算符,编译器不会再自动生成拷贝构造函数和拷贝赋值运算符。

声明时给缺省值

在 C++11 之前,默认参数值只能在函数声明中给出,不能直接在成员变量定义时赋值。而 C++11 允许在类的成员变量声明时直接赋默认值,这一特性提高了代码的简洁性,并增强了初始化的灵活性。这样,在构造对象时,若未传入对应参数,成员变量会自动采用声明时指定的默认值。

示例代码

class Person {
public:
    Person(const char* name = "") : _name(name) {}

private:
    std::string _name = "DefaultName"; // 直接在声明中赋缺省值
    int _age = 18; // 默认值为 18
};

int main() {
    Person p; // _name 初始化为 "DefaultName",_age 初始化为 18
    
    return 0;
}

通过在声明时赋值,减少了构造函数中初始化的代码量,避免重复设置默认值,提高了可读性。

defaultdelete

C++11 引入了 =default=delete,提供更精细的控制:

  • =default:当类中定义了某个自定义函数(如拷贝构造),编译器不会自动生成移动构造函数。若希望保留自动生成的行为,可使用 =default 显式要求编译器生成该函数。
  • =delete:通过 =delete,可以禁用类的某些默认行为(如拷贝或赋值),例如禁用拷贝构造可以避免误用拷贝构造函数带来的资源分配问题。

示例代码:

class Person {
public:
Person(const char* name = "", int age = 0)
: _name(name), _age(age) {}

Person(const Person& p) = delete; // 禁用拷贝构造函数
Person(Person&& p) = default;      // 显式要求生成默认移动构造函数

private:
std::string _name;
int _age;
};

int main() {
    Person s1("Alice", 25);
    // Person s2 = s1; // 错误:拷贝构造函数被禁用
    Person s3 = std::move(s1); // 调用默认的移动构造函数
    return 0;
}

finaloverride

在 C++ 的继承和多态中,派生类可能会误写或错写基类的虚函数,导致未按预期覆盖基类的行为。C++11 提供了 finaloverride 关键字,帮助开发者更好地控制和检测继承链中的函数覆盖行为。

  • override:用于修饰派生类中的虚函数,表示这是对基类中同名虚函数的覆盖。如果函数签名不匹配,编译器会报错。
  • final:用于修饰类或虚函数,表示该类或虚函数不允许被进一步继承或重写。
示例代码
class Base {
public:
    virtual void display() const {
        std::cout << "Base class display" << std::endl;
    }

    virtual void show() const final { // 不允许派生类重写此函数
        std::cout << "Base class show" << std::endl;
    }
};

class Derived : public Base {
public:
    void display() const override { // 正确覆盖基类的display
        std::cout << "Derived class display" << std::endl;
    }
    // void show() const override; // 错误:不能重写final函数
};

// class FurtherDerived : public Derived final {}; // 不允许进一步派生

override 关键字帮助避免虚函数重写错误,final 关键字则能阻止类或函数的进一步派生和重写,提升代码安全性和可读性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2237526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

emr上使用sparkrunner运行beam数据流水线

参考资料 https://time.geekbang.org/column/intro/167?tabcatalog Apache Beam和其他开源项目不太一样&#xff0c;它并不是一个数据处理平台&#xff0c;本身也无法对数据进行处理。Beam所提供的是一个统一的编程模型思想&#xff0c;而我们可以通过这个统一出来的接口来编…

github高分项目 WGCLOUD - 运维实时管理工具

GitHub - tianshiyeben/wgcloud: Linux运维监控工具&#xff0c;支持系统硬件信息&#xff0c;内存&#xff0c;CPU&#xff0c;温度&#xff0c;磁盘空间及IO&#xff0c;硬盘smart&#xff0c;GPU&#xff0c;防火墙&#xff0c;网络流量速率等监控&#xff0c;服务接口监测&…

MyBatisPlus 用法详解

文章目录 一、快速入门1.1 引入依赖&#xff1a;1.2 定义 Mappper&#xff1a;1.3 使用演示&#xff1a;1.4 常见注解&#xff1a;1.4.1 TableName:1.4.2 TableId&#xff1a;1.4.3 TableField&#xff1a; 1.5 常见配置&#xff1a; 二、核心功能2.1 条件构造器&#xff1a;2.…

Python小游戏23——捕鱼达人

首先&#xff0c;你需要安装Pygame库。如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 运行效果展示 接下来是示例代码&#xff1a; 【python】 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 SCREEN…

库打包工具 rollup

库打包工具 rollup 摘要 **概念&#xff1a;**rollup是一个模块化的打包工具 注&#xff1a;实际应用中&#xff0c;rollup更多是一个库打包工具 与Webpack的区别&#xff1a; 文件处理&#xff1a; rollup 更多专注于 JS 代码&#xff0c;并针对 ES Module 进行打包webpa…

基于SSM+VUE小学生素质成长记录平台JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

【架构设计常见技术】

EJB EJB是服务器端的组件模型&#xff0c;使开发者能够构建可扩展、分布式的业务逻辑组件。这些组件运行在EJB容器中&#xff0c;EJB将各功能模块封装成独立的组件&#xff0c;能够被不同的客户端应用程序调用&#xff0c;简化开发过程&#xff0c;支持分布式应用开发。 IOC …

优选算法 - 1 ( 双指针 移动窗口 8000 字详解 )

一&#xff1a;双指针 1.1 移动零 题目链接&#xff1a;283.移动零 class Solution {public void moveZeroes(int[] nums) {for(int cur 0, dest -1 ; cur < nums.length ; cur){if(nums[cur] 0){}else{dest; // dest 先向后移动⼀位int tmp nums[cur];nums[cur] num…

鸿蒙操作系统是什么?与安卓系统有什么区别?

鸿蒙操作系统 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是华为公司发布的一款基于微内核的面向全场景的分布式操作系统。 发展历程&#xff1a; 早期规划&#xff1a;华为从2012 年开始规划自有操作系统&#xff0c;并在芬兰赫尔辛基设立智能手机研发中心&#xff0c;招…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

第二届计算机网络技术与电子信息工程国际学术会议(CNTEIE 2024,12月6-8日)

第二届计算机网络技术与电子信息工程国际学术会议&#xff08;CNTEIE 2024&#xff09; 2024 2nd International Conference on Computer Network Technology and Electronic and Information Engineering 重要信息 会议官网&#xff1a;www.cnteie.org 2024 2nd Internation…

Git 入门篇(一)

前言 操作系统&#xff1a;win11 64位 与gitee搭配使用 Git 入门篇&#xff08;一&#xff09; Git 入门篇&#xff08;二&#xff09; Git 入门篇&#xff08;三&#xff09; 目录 git下载、安装与配置 下载 安装 配置 git下载、安装与配置 下载 官网&#xff1a;git-…

WPS文档中的“等线”如何删除

如何删除“等线”占用的行如何删除表格之间的空行WPS文档中的“等线”是什么如果删除脚注文本占用的行 如下这种&#xff0c;在文档中添加了表格和脚注&#xff0c;发现上下表格之间有多行空行&#xff0c;鼠标选中&#xff0c;显示是“等线”&#xff0c;那么如何去除等线占用…

题目讲解15 合并两个排序的链表

原题链接&#xff1a; 合并两个排序的链表_牛客题霸_牛客网 思路分析&#xff1a; 第一步&#xff1a;写一个链表尾插数据的方法。 typedef struct ListNode ListNode;//申请结点 ListNode* BuyNode(int x) {ListNode* node (ListNode*)malloc(sizeof(ListNode));node->…

计算机网络基本概念总结

IP地址 概念 使网络中的设备都有唯一的地址标识&#xff0c;用于表示其在网络中的位置。 格式 IP地址是一个32位的二进制数&#xff0c;通常被分割为4个8位二进制数&#xff08;也就是4个字节&#xff09;&#xff0c;如&#xff1a;01100100.00001000.00001010.00000110。通常…

Pandas | 特征列大量数据异常需要填充数据时注意事项

问题描述 一组数据如下&#xff1a; df.isnull().sum()城市 0 名称 0 星级 1529 评分 0 价格 1 销量 1 省/市/区 0 坐标 0 简介 41 是否免费 0 具体地址 3 dtype: int64df[星级]0…

Science Robotics 综述揭示演化研究新范式,从机器人复活远古生物!

在地球46亿年的漫长历史长河中&#xff0c;生命的演化过程充满着未解之谜。如何从零散的化石证据中还原古生物的真实面貌&#xff1f;如何理解关键演化节点的具体过程&#xff1f;10月23日&#xff0c;Science Robotics发表重磅综述&#xff0c;首次系统性提出"古生物启发…

[编译报错]ImportError: No module named _sqlite3解决办法

1. 问题描述&#xff1a; 在使用python进行代码编译时&#xff0c;提示下面报错&#xff1a; "/home/bspuser/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py", line 18, in <module>import sqlite3File "/usr/local/lib/python2.7/sqlite3/_…

EasyExcel的AbstractColumnWidthStyleStrategy注入CellStyle不生效

设置背景色 CellStyle style workbook.createCellStyle();style.setFillForegroundColor(IndexedColors.RED.getIndex()); // 是设置前景色不是背景色style.setFillPattern(FillPatternType.SOLID_FOREGROUND)EasyExcel.writerTable(0).head(Head1.class).registerWriteHandl…

iphone怎么删除重复的照片的新策略

Phone用户常常面临存储空间不足的问题&#xff0c;其中一个主要原因是相册中的重复照片。这些重复项不仅占用了大量的存储空间&#xff0c;还会影响设备的整体性能。本文将向您展示iphone怎么删除重复的照片的方法&#xff0c;包括一些利用工具来自动化这个过程的创新方法。 识…