C++ 类的六个特殊成员函数

news/2025/3/25 9:31:42/

简 述: 分析 C++ Class 的六个特殊成员函数 wiki ,并且手动实现一番;

  1. 默认构造函数
  2. 析构函数
  3. 复制构造函数
  4. 复制赋值运算符
  5. 移动构造函数
  6. 移动赋值运算符

文章目录

      • 原理
      • 代码
      • 系列


本文初发于 “偕臧的小站”,同步转载于此。


原理

​ 特殊成员函数是类(或结构)成员函数,在某些情况下,编译器会自动为你生成。

  1. default constructor: 通常没有参数,但可以具有带默认值的参数。
  2. destructor: 销毁对象的前一刻执行清理
  3. copy constructor:新建的的对象进行初始化,形参是 const T&
  4. copy assignment constructor:已有的对象进行赋值,形参是 const T&
  5. move constructor:新建的的对象进行初始化,形参是 T &&
  6. move assignment constructor:已有的对象进行赋值,形参是 T &&

  • move 的函数相对于 copy 的函数没有 const

  • copy 是属完整的再复制拷贝一份;move 是对将亡的右值进行指针互换、节省空间提升效率

  • ”复制 / 移动构造函数“ 属于新建对象,无需判断两者是否相等;”复制 / 移动赋值运算符“ 属于已有的对象进行赋值,赋值时需要先判断两者是否相等。

  • 若有深拷贝时,”复制 / 移动赋值运算符“ 除了判断相等、数值是否有效;在拷贝字节前,还要先释放旧资源

  • 只有当类存储了需要释放的系统资源的句柄,或拥有其指向的内存的指针时,你才需要定义自定义 ”析构函数“

  • 三五法则 cppreference.com


代码

💻 win10 22H2 📎 Visual Studio 2019 📎 C++17

/******************************************************************** Copyright (c) 2022~2023 XMuli  All rights reserved.* Description: C++ 类的六个特殊成员函数******************************************************************/
#pragma once
#include <iostream>
#include <utility>
using namespace std;class A
{
public:A() : m_ptr(nullptr) {std::cout << "default constructor" << endl;}A(const char* s) : m_ptr(nullptr) {std::cout << "no-default-val constructor" << endl;if (s) {auto n = std::strlen(s) + 1;m_ptr = new char[n];std::memcpy(m_ptr, s, n);}}A(const A& other): m_ptr(nullptr) {std::cout << "copy constructor" << endl;if (other.m_ptr) {auto n = std::strlen(other.m_ptr) + 1;m_ptr = new char[n];std::memcpy(m_ptr, other.m_ptr, n);}}A& operator = (const A& other) {std::cout << "copy assignment constructor" << endl;if (this != &other) {delete[] m_ptr;  // Free the existing resource.  重点 !!!if (other.m_ptr != nullptr) {auto n = std::strlen(other.m_ptr) + 1;m_ptr = new char[n];std::memcpy(m_ptr, other.m_ptr, n);}}return *this;}A(A&& other) noexcept    // 行参无 const: m_ptr(nullptr) {std::cout << "move constructor" << endl;if (other.m_ptr)m_ptr = std::move(other.m_ptr);other.m_ptr = nullptr;}A& operator=(A&& other) noexcept {  // 行参无 conststd::cout << "move assignment constructor" << endl;if (this != &other) {delete[] m_ptr;  // Free the existing resource.if (other.m_ptr)m_ptr = std::move(other.m_ptr);other.m_ptr = nullptr;}return *this;}~A() {std::cout << "destructor" << endl;if (m_ptr)delete[] m_ptr;}private:char* m_ptr;
};A fn() {A t("A fun()");return t;
}int main()
{A a1("a1");                // default constructorA a2(a1);                  // copy constructorA a3 = a1;                 // copy constructora1 = a3;                   // copy assignment constructorstd::cout << "----------------------------\n\n";//fn();                    // function returning a A objectA a5 = std::move(a1);      // move constructorA a6;                      // default constructora6 = std::move(a1);        // move assignment constructorstd::cout << "Hello World!\n";return 0;
}/*************************** 运行结果 *******************************
* no-default-val constructor
copy constructor
copy constructor
copy assignment constructor
----------------------------move constructor
default constructor
move assignment constructor
Hello World!
destructor
destructor
destructor
destructor
destructor******************************************************************/

拷贝构造函数是 A a2(a1); 形式,还可以是 A a3 = a1; 这种形式。关键看是新创建对象还是已有的对象赋值。move 的函数赋值,借助 std::move() 将左值转换为右值。


系列

QtExamples 的 SpecialMembers.h

欢迎 star ⭐ 和 fork 🍴这个系列的 C++ / QT / DTK 学习,附学习由浅入深的目录。


http://www.ppmy.cn/news/5124.html

相关文章

4.http模块

http模块是Node.js官方提供创建web服务器的模块&#xff0c;在使用http模块前首先导入http模块 目录 1 一些概念 1.1 IP 1.2 域名 1.3 端口 2 创建一个基本的web服务器 3 req请求对象 4 res响应对象 5 不同地址获取不同响应 6 在服务中加载html文件 6.1 基…

安装ZIMG 图片服务器

简介&#xff1a;zimg是图像存储和处理服务器。您可以使用URL参数从zimg获取压缩和缩放的图像。 zimg的并发I / O&#xff0c;分布式存储和时间处理能力非常出色。 您不再需要在图像服务器中使用nginx。在基准测试中&#xff0c;zimg可以在高并发级别上处理每秒3000图像下载任务…

实战三十二:基于knn算法的用户购物消费预测代码+数据

K近邻算法通过计算被分类对象与训练集对象之间的距离,确定其k个临近点,然后使用这k个临近点中最多的分类作为分类结果。 如上图,当K=3时,它会被分类为 Class B。因为K=3时,3个临近点里有2个是B类的。 同理,K=7时它会被分类为 Class A,因为K=7时,7个临近点里4个是A类的…

【Three.js入门】图形用户界面GUI、BufferGeometry创建矩形、随机生成多个随机颜色的三角形

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

MCMC算法

一. MCMC算法定义 MCMC是Markov chain Monte Carlo的缩写&#xff0c;即马尔可夫链蒙特卡罗方法。MCMC是一组利用马尔可夫链从随机分布中取样的算法。生成的马氏链即是对于目标分布的近似估计。常见算法&#xff1a; Metropolis-Hastings算法Gibbs取样算法Hamiltonian Monte C…

SpringMVC的AOP总结

SpringMVC的AOP总结 1、Filter 过滤器 Filter是Servlet规范中规定的&#xff0c;只能用于WEB中, 在Servlet前后起作用 它可以对几乎所有请求进行过滤&#xff0c;但是缺点是一个过滤器实例只能在容器初始化时调用一次 使用场景: 修改字符编码; 对入参进行校验, 校验不通过返回…

sklearn.metrics中micro和macro的区别

sklearn安装 先看以下示例&#xff0c;区分micro和macro的区别&#xff0c;这里直接调用sklearn封装好的接口&#xff0c;如果没有安装sklearn可以使用以下命令进行安装&#xff1a; pip install scikit-learn如果直接使用 pip install sklearn是没有作用的&#xff0c;将会…

Java真的不难(五十二)Stream流的深入理解与流式编程

Stream流的深入理解与流式编程&#xff1a; 在今年年初小应学长也写过Stream与Lambda的两篇文章&#xff0c;今天先将两者结合起来进行流式编程 一、关于这两者 Stream与Lambda都是Java8引入的新概念&#xff0c;lambda在Java编程中对于函数式编程的支持&#xff0c;有助于代…