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

【C++拷贝构造函数深浅拷贝】

拷贝构造函数

注意:访问权限是public

拷贝构造函数:类名(const  类名& 对象名){}  可以有多个参数  。 没有常引用就是普通构造函数

如果不写,编译器自己会给一个(作用仅仅是赋值,默认拷贝构造函数一直都在)

#include<iostream>
using namespace std;class person {
public:int age;string name;person(int age,string name):age(age),name(name) {cout << "含参构造函数" << endl; }person(const person& p) {age = p.age;name = p.name;cout << "拷贝构造函数" << endl;}void show() {cout << "姓名:" << name << " | 年龄:" << age << endl;}~person() { cout << "析构函数" << endl; }
};int main()
{person p1(100,"xxx");person p2(p1);   //p2=p1 效果一样p1.show();p2.show();return 0;
}

函数值传递过程中会调用拷贝构造函数,因为函数形参本身就是一份赋值(值传递)

//伪代码
//注意,传引用和指针都不会激活拷贝构造
void f(person p) {p.show();
}person p;
f(p);void g(person* p){p->show();
}person *p=new person(x);  //有参就调用有参构造,否则默认构造
g(p);
delete(p);   //调用析构
p=NULL;

函数以值的方式返回对象时,可能会调用拷贝构造函数(vs会,linux不会,g++做了优化)

//伪代码
person f(person p)
{person pf(p);return pf;
}
person p(1, "sdf");
person p2 = f(p);
p2.show();//引用1
person& g()
{person p;    //每读到这句就一个默认构造return p;    //g函数结束就析构p
}
person p;
g()=p;
g().show();   //乱码//引用2
person& g(person& p)
{return p;
}
person p1;
person p2;
g(p1)=p2;
g(p1)->show();  //p2的值

注意析构函数调用时机:作用域结束(mian函数结束)

如果类重载拷贝构造函数,却没有定义默认构造函数,编译器会提供一个

class person {int age;person(int a):age(a){cout << "有参构造" << endl;}//person(const person& p) {     //注释默认构造//	cout << "默认拷贝构造" << endl;//	age = p.age;//}person(const person& p, int i){age = i;cout << "重载拷贝构造" << endl;}void show() {cout << "age:" << age << endl;}
};int main()
{person p(10);p.show();person p2(p);     //编译器又提供一个 p2.show(); return 0;
}

深浅拷贝

对空指针解引用是非法的       

#include<iostream>
using namespace std;class person {
public:int a;int* p;person(){a = 0; p = nullptr;cout << "person构造函数" << endl;}person(const person& per){a = per.a;//p = per.p;  //浅拷贝//深拷贝p = new int;    //分配内存*p = *per.p;    //拷贝数据cout << "person拷贝构造函数" << endl;}~person()   //浅拷贝问题:p1和p2指向同一个空间,p1销毁后,到p2销毁就会崩溃{delete p; p = nullptr;cout << "person析构函数" << endl;}void show(){cout << a << " " << p << " " << *p << endl;}
};int main()
{person p1;p1.a = 10; p1.p = new int(2);p1.show();person p2(p1);p2.show();return 0;
}

http://www.lryc.cn/news/373964.html

相关文章:

  • 快速编译安装tensorrt_yolo
  • 外盘黄金期货需要注意什么?
  • Allegro光绘Gerber文件、IPC网表、坐标文件、装配PDF文件导出打包
  • mysql的索引可以分为哪些类型
  • Content type ‘application/x-www-form-urlencoded;charset=UTF-8‘ not supported
  • 【JavaEE进阶】——利用框架完成功能全面的图书管理系统
  • WDF驱动开发-内存缓冲区
  • c语言连接两个字符串
  • 基于springboot的大学计算机基础网络教学系统
  • UOS常用命令
  • vue3 如何给表单添加表单效验+正则表达式
  • JavaScript算法实现dfs查找省市区路径
  • map文件分析
  • MySQL-创建表~数据类型
  • 【鸿蒙 HarmonyOS】Swiper组件
  • 玩具机器人脚本适合场景
  • 人工智能模型组合学习的理论和实验实践
  • MySQL备份与恢复:确保数据的安全与可靠性
  • Noisee AI – AI音乐影片MV在线生成工具,专门为Suno的好搭子来了~
  • 实战计算机网络02——物理层
  • Doris:冷热分层
  • 28.启动与暂停程序
  • 404 页面代码
  • java设计模式和面向对象编程思想
  • 超万卡训练集群网络互联技术解读
  • AtomicInteger类介绍
  • Es 索引查询排序分析
  • 【C语言】解决C语言报错:Format String Vulnerability
  • Python深度学习:Bi-LSTM和LSTM在网络上有什么区别,对比来看
  • Keepalived LVS群集