C++ 类编译器自动生成的默认函数 | 拷贝构造函数 vs 拷贝赋值运算符(赋值构造)
C 类编译器自动生成的默认函数当你写一个类不手动写这些成员函数时C 编译器会在满足条件下自动生成 6 个特殊成员函数默认构造函数拷贝构造函数拷贝赋值运算符operator移动构造函数C11 新增移动赋值运算符C11 新增析构函数注意编译器生成不代表一定生成如果你自己手写了其中一个会抑制部分自动生成。1. 默认构造函数类名()触发生成条件类没有写任何构造函数编译器自动生成一个无参默认构造。cppclass Test{ public: //编译器自动生成Test(){} }; Test t; //可以调用自动生成的构造函数体是空不会初始化成员变量内置类型 (int*,double 等)堆 / 栈上是随机垃圾值类类型成员会调用它自己的默认构造❗抑制生成编译器不再自动生成默认构造只要你手写了任意一个构造函数有参、拷贝构造编译器就不会生成默认构造。cppclass Test{ public: Test(int a){} }; Test t; //编译报错没有无参构造编译器不会自动补2. 析构函数~类名()触发生成条件没有手写析构函数编译器自动生成默认析构。cppclass Test{ //编译器生成 ~Test(){} };函数体空会自动调用成员、父类的析构。默认析构不是 virtual只有基类手写virtual ~A()才是虚析构。重点做多态继承基类要手动写 virtual 析构编译器生成的析构没有 virtual。抑制生成手写析构函数编译器不再生成默认析构。3. 拷贝构造函数Test(const Test other)格式拷贝构造参数必须是本类的引用一般 const 引用触发生成条件没有手写拷贝构造函数编译器自动生成浅拷贝拷贝构造。浅拷贝逐成员拷贝值拷贝int、指针直接复制值指针只复制地址不复制指向的堆内存类成员调用该成员自己的拷贝构造。示例cppclass B{ public: int* p; //编译器自动生成 B(const B other): p(other.p) {} }; B b1; b1.p new int[100]; B b2 b1; //调用自动生成拷贝构造b2.p 和 b1.p指向同一块堆内存 //析构的时候两个对象delete[]p**重复释放程序崩溃**这就是经典浅拷贝 bug有堆资源需要自己手写深拷贝。抑制生成手写拷贝构造编译器不再自动生成。4. 拷贝赋值运算符Test operator(const Test other)触发生成条件没有手写operator编译器自动生成同样是浅拷贝逐成员赋值。cppB b1,b2; b1.p new int[10]; b2 b1; //调用编译器生成赋值b2.p b1.p指针共享堆内存返回值是Test支持链式赋值abc。抑制生成手写拷贝赋值编译器不生成。拷贝构造创建新对象拷贝赋值对象已经存在把别的对象赋值给已经存在的对象。5. 移动构造函数Test(Test other)C11触发生成条件没有手写拷贝构造、拷贝赋值、移动构造、移动赋值、析构编译器才自动生成移动构造。参数是右值引用 作用把临时对象的资源偷过来不用拷贝性能高。编译器自动生成版本逐成员移动。⚠只要你手写了析构 / 拷贝构造编译器就不会自动生成移动构造6. 移动赋值运算符Test operator(Test other)C11触发生成条件同上五个函数都没有手动写编译器才生成移动赋值执行逐成员移动。移动语义例子cppTest func(){ Test t; return t; //返回临时对象会调用移动构造 } Test obj func();一张表什么时候编译器自动生成重点记忆表格自动生成函数什么时候编译器生成什么操作会抑制它不再生成默认构造Test()没有手写任何构造函数手写任意构造有参、拷贝构造析构~Test()没有手写析构函数手写析构函数拷贝构造Test(const Test)没有手写拷贝构造手写拷贝构造拷贝赋值operator(const Test)没有手写拷贝赋值手写拷贝赋值移动构造Test(Test)C11拷贝、赋值、析构全都没写手写拷贝构造 / 拷贝赋值 / 移动构造 / 移动赋值 / 析构移动赋值operator(Test)C11拷贝、赋值、析构全都没写手写拷贝构造 / 拷贝赋值 / 移动构造 / 移动赋值 / 析构古老规则如果你手写了析构编译器依然生成拷贝构造、拷贝赋值但是不会生成移动版本。四 / 五法则工程必背三法则C98如果你手动写了其中一个析构 / 拷贝构造 / 拷贝赋值那么另外两个也应该手写。场景类内部持有堆内存指针手写析构做 delete那拷贝构造、拷贝赋值必须手写深拷贝否则浅拷贝造成双重释放崩溃。五法则C11写了析构 / 拷贝构造 / 拷贝赋值建议同时手写移动构造、移动赋值。也可以用default显式让编译器生成delete禁止生成。default 和 delete 用法cppclass Test { public: Test() default; //强制编译器生成默认构造 Test(const Test) default; //强制生成拷贝构造 Test operator(const Test) delete; //删除拷贝赋值禁止赋值 ~Test() default; };举例子结合你刚刚代码中的 B 类cppclass B : public A { int *p; //堆指针 public: B(){ pnew int[1024]; } //手写构造编译器不会生成默认构造 ~B(){ delete[] p; } //手写析构 //编译器自动生成拷贝构造 B(const B b):p(b.p){} 浅拷贝 //编译器自动生成拷贝赋值 operator(const Bb){ pb.p; }浅拷贝 //⚠因为手写析构编译器**不会自动生成移动构造、移动赋值** };B 这里编译器生成的拷贝构造是浅拷贝如果执行B b2 b1两个对象 p 指向同一块堆内存析构的时候两次 delete [] p直接崩溃。这种类就必须自己手写深拷贝的拷贝构造和拷贝赋值遵守三法则。手写深拷贝示例cppB(const B other) { p new int[1024]; //分配自己独立堆内存 memcpy(p,other.p,1024*sizeof(int)); coutB深拷贝构造endl; } B operator(const B other) { if(this other) return *this; //防止自赋值 delete[] p; //释放旧资源 p new int[1024]; memcpy(p,other.p,1024*sizeof(int)); return *this; }补充误区编译器自动生成析构不是 virtual只有基类手动写virtual ~A(){}才是虚析构。自动拷贝构造是浅拷贝指针成员只会复制地址不会复制堆内存。只要手写析构移动构造、移动赋值就不会自动生成C11 规则。默认构造不会初始化内置类型成员栈对象 int / 指针成员是垃圾值。如果你需要我可以写一份完整可运行 demo演示浅拷贝崩溃、深拷贝、default、delete 全部效果。拷贝构造函数 vs 拷贝赋值运算符赋值构造拷贝构造创建新对象 拷贝赋值对象已经存在给已有的对象赋值。1. 函数写法① 拷贝构造函数cpp// 拷贝构造参数必须是同类的引用const 是推荐写法 class Test { public: int* p; //拷贝构造函数 Test(const Test other) { cout 拷贝构造函数 endl; //浅拷贝版本 //p other.p; //深拷贝版本持有堆内存必须深拷贝 p new int[100]; memcpy(p, other.p, 100*sizeof(int)); } };函数没有返回值名字和类名完全一样。参数必须是本类引用不能传值Test(Test other)会无限递归。② 拷贝赋值运算符 operatorcppclass Test { public: int* p; Test operator(const Test other) { cout 拷贝赋值运算符 endl; //1. 处理自赋值自己赋值给自己直接返回 if(this other) { return *this; } //2. 释放自己旧的堆资源 delete[] p; //3. 分配新内存拷贝数据深拷贝 p new int[100]; memcpy(p, other.p, 100*sizeof(int)); //4. 返回*this支持链式赋值 abc; return *this; } };返回值必须是Test引用支持链式赋值。参数同样用const Test other。2. 触发调用场景核心区别cppTest t1; t1.p new int[100]; // 调用【拷贝构造】正在创建新对象 Test t2 t1; //定义新对象用别的对象初始化 Test t3(t1); //直接调用拷贝构造 Test t4{t1}; Test func(Test tmp){ return tmp; } Test t5 func(t1); //函数返回、传值参数也会触发拷贝构造 // 调用【拷贝赋值operator】对象已经存在 Test t6; t6.p new int[100]; t6 t1; // t6已经存在把t1赋值给t6 → 拷贝赋值表格项目拷贝构造函数拷贝赋值运算符operator本质创建一个全新对象对象已经存在覆盖原有对象内容函数签名Test(const Test other)无返回值Test operator(const Test other)返回引用*this调用时机定义新对象时初始化Test t2 t1;对象已经实例化完成执行t6 t1;赋值堆内存处理不需要释放旧内存新对象还没有分配资源必须先释放自己旧的堆内存防止内存泄漏自赋值判断不需要新对象不存在自己的资源必须判断this other否则 delete 自己内存直接崩溃重点坑拷贝构造新对象还没有旧堆内存不要写 delete拷贝赋值对象已经存在里面有旧堆内存一定要先 delete [] 释放旧资源否则内存泄漏还要判断自赋值。3. 浅拷贝版本编译器自动生成的版本编译器自动生成的版本两者都是简单逐成员复制浅拷贝cpp//编译器生成拷贝构造 Test(const Test other): p(other.p) { } //编译器生成拷贝赋值 Test operator(const Test other) { p other.p; return *this; }只复制指针的值两个对象p指向同一块堆内存析构的时候两次 delete []程序崩溃。只要类里面有指针指向堆内存必须手动写深拷贝版本4. 完整可运行示例cpp#include iostream #include cstring using namespace std; class Test { public: int* p; Test() { p new int[100]; cout 默认构造 endl; } //拷贝构造函数深拷贝 Test(const Test other) { cout 拷贝构造执行 endl; p new int[100]; memcpy(p, other.p, sizeof(int)*100); } //拷贝赋值运算符深拷贝 Test operator(const Test other) { cout 拷贝赋值执行 endl; //自赋值检测 if(this other) return *this; //释放自身旧资源 delete[] p; //分配新内存复制 p new int[100]; memcpy(p, other.p, sizeof(int)*100); return *this; } ~Test() { delete[] p; cout 析构 endl; } }; int main() { Test t1; Test t2 t1; //拷贝构造新建t2 Test t3; t3 t1; //拷贝赋值t3已经存在 return 0; }输出plaintext默认构造 拷贝构造执行 默认构造 拷贝赋值执行 析构 析构 析构5. 常见混淆cppTest t2(t1); //拷贝构造 Test t2 t1; //拷贝构造不是赋值这里是初始化t2刚创建 Test t2; t2 t1; //拷贝赋值t2早已创建完毕6. 三法则回顾如果手写了析构里面做 delete 堆内存必须同时手写拷贝构造、拷贝赋值运算符否则编译器生成浅拷贝会双重释放崩溃。补充禁止拷贝如果你不想对象被拷贝 / 赋值可以用deletecppTest(const Test) delete; Test operator(const Test) delete;如果你想我可以再对比移动构造和移动赋值的写法与区别。

相关新闻

多态的理解,虚函数表的理解

多态的理解,虚函数表的理解

#include <iostream> using namespace std;class Plane { public:virtual void fly(){cout << "灰机正在飞行" << endl;}virtual void showInfo(){cout << "灰机正在展示" << endl;} };class AirBus : public Plane { publ…

2026/8/21 5:46:42 阅读更多 →
2026独立站建站平台有哪些?快来一起看看吧!

2026独立站建站平台有哪些?快来一起看看吧!

2026独立站建站平台有哪些&#xff1f;快来一起看看吧&#xff01;据Market Research Future发布的《2026年全球电商科技趋势报告》显示&#xff0c;预计到2026年底&#xff0c;全球独立站数量将突破5亿大关。但在独立站出海的浪潮中&#xff0c;不少初创团队却频频在起跑线上栽…

2026/8/21 6:20:51 阅读更多 →
2026小程序模板平台哪个好?新手搭建如何不踩雷?

2026小程序模板平台哪个好?新手搭建如何不踩雷?

2026小程序模板平台哪个好&#xff1f;新手搭建如何不踩雷&#xff1f;据中国信通院发布的《2025年中小企业数字化转型白皮书》显示&#xff0c;2025年我国中小企业数字化转型渗透率达48.6%&#xff0c;小程序凭借轻量化、获客成本低的优势&#xff0c;成为中小商家线上经营的首…

2026/8/21 7:03:58 阅读更多 →

最新新闻

FastAPI快速构建LLM应用:从环境配置到生产部署实战指南

FastAPI快速构建LLM应用:从环境配置到生产部署实战指南

1. 先搞清楚 FastAPI 和 LLM 项目到底能解决什么问题如果你正在找一个能快速把想法变成 API 服务&#xff0c;并且想用它来对接大语言模型&#xff08;LLM&#xff09;做点实际应用&#xff0c;那 FastAPI 几乎是目前 Python 领域最直接的选择。它不是一个需要花几个月去学的重…

2026/8/21 8:54:46 阅读更多 →
WordPress插件开发实战:从零构建Airbnb式短租平台

WordPress插件开发实战:从零构建Airbnb式短租平台

在 WordPress 上构建一个类似 Airbnb 的短租平台&#xff0c;听起来像是一个庞大的工程&#xff0c;但借助 WordPress 强大的插件生态和内容管理能力&#xff0c;这并非遥不可及。许多开发者都曾尝试将复杂的业务逻辑集成到 WordPress 中&#xff0c;但往往卡在如何将房源管理、…

2026/8/21 8:54:46 阅读更多 →
MHmarkets:从公开信息出发 复盘技术架构与产品理解成本

MHmarkets:从公开信息出发 复盘技术架构与产品理解成本

对新手与注重稳健体验的外汇内容读者而言&#xff0c;“能看懂”往往比“堆概念”更重要。围绕MHmarkets&#xff0c;以下重点写清解释是否通俗、规则是否易查、提示是否前置&#xff0c;以及服务是否具备连续性。在外汇相关服务中&#xff0c;读者最在意的通常是信息是否清楚、…

2026/8/21 8:54:46 阅读更多 →
C#关于同步方法里面调用异步方法的探究

C#关于同步方法里面调用异步方法的探究

前言 我在写代码的时候(.net core)有时候会碰到void方法里,调用async方法并且Wait,而且我还看到别人这么写了。而且我这么写的时候,编译器没有提示任何警告。但是看了dudu的文章:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相 了解了,这样写是有…

2026/8/21 8:54:45 阅读更多 →
SovereignNegotiation-Bench:评估AI代理在隐私与合规约束下的谈判能力

SovereignNegotiation-Bench:评估AI代理在隐私与合规约束下的谈判能力

1. 项目概述&#xff1a;当你的数字替身去谈判 想象一下&#xff0c;你需要在网上购买一项服务&#xff0c;比如一份保险&#xff0c;或者租一套房子。传统的流程是&#xff0c;你打开一个网站或App&#xff0c;面对一个由平台设定的、充满复杂条款和隐藏选项的界面&#xff0c…

2026/8/21 8:54:45 阅读更多 →
卡尔曼滤波实战:从原理到代码,掌握目标跟踪与状态估计

卡尔曼滤波实战:从原理到代码,掌握目标跟踪与状态估计

这类算法教程最值得先看的不是它列了多少公式&#xff0c;而是能不能帮你把“预测-更新”这个核心循环真正用起来。卡尔曼滤波在目标跟踪、传感器融合、状态估计这些场景里几乎是绕不开的&#xff0c;但很多人卡在理论推导和代码落地之间&#xff0c;感觉懂了又好像没完全懂。 …

2026/8/21 8:53:43 阅读更多 →

日新闻

机场边检旅客定位系统国产化白皮书:算法、硬件、底座平台全程自主

机场边检旅客定位系统国产化白皮书:算法、硬件、底座平台全程自主

前言随着国家数字基础设施信创替代、关键技术自主可控战略持续深化&#xff0c;口岸智慧安防、边检智能管控领域正全面进入国产化、自主化、安全可控升级周期。当前国内机场边检旅客识别与定位体系长期依赖国外商用视觉算法、进口成像硬件、闭源通用计算平台&#xff0c;存在核…

2026/8/21 0:00:42 阅读更多 →
别再把“数字孪生”当空间智能了!镜像视界揭开四维时空的真正面纱

别再把“数字孪生”当空间智能了!镜像视界揭开四维时空的真正面纱

别再把“数字孪生”当空间智能了&#xff01;镜像视界揭开四维时空的真正面纱当下数字化建设浪潮中&#xff0c;很多项目将三维可视化、视频贴图叠加的数字孪生等同于空间智能。传统数字孪生更多停留在三维场景复刻&#xff0c;擅长把物理世界“画出来、展示出来”&#xff0c;…

2026/8/21 0:00:42 阅读更多 →
105、车载温度范围-40°C到85°C的影像质量一致性——ISP参数温漂补偿与产线标定策略

105、车载温度范围-40°C到85°C的影像质量一致性——ISP参数温漂补偿与产线标定策略

105、车载温度范围-40C到85C的影像质量一致性——ISP参数温漂补偿与产线标定策略 去年冬天在北方某车厂做A样评审,凌晨四点的黑河试验场,零下三十三度。客户拿了一台冷启动的车,中控屏上倒车影像全是雪花噪点,暗部细节直接糊成一片。我第一反应是sensor温度没上来,暗电流…

2026/8/21 0:00:42 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者&#xff0c;最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent&#xff0c;从本地部署到云端API&#xff0c;我们正处在一个技术栈快速重构的节点。然而&#xff0c;面对层出不穷的模型、框架和工具&#xf…

2026/8/21 3:21:33 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/21 0:02:09 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

2026/8/21 6:07:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速&#xff1a;macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/20 6:11:08 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南&#xff1a;3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗&#xff1f;ncmdump解密工具帮你轻松解决这个困…

2026/8/20 21:46:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片&#xff1a;为英语学习 App 打造桌面级学习助手适用平台&#xff1a;HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0&#xff08;API 26 Beta&#xff09;新增了 AgentCard 智能体卡片能力&#xff0c;这是继 HMAF&#xff08;鸿蒙智能体框架&#x…

2026/8/21 0:14:22 阅读更多 →