C++之一些事一些情--深拷贝和浅拷贝
来源:互联网 发布:.top域名怎么样 编辑:程序博客网 时间:2024/06/05 00:31
1、拷贝构造函数的出现场景
以下是String类的一个简单定义,用于说明一些例子:
class String{public: String(const char *ch=NULL);//默认构造函数 String(const String &str);//拷贝构造函数 ~String(void);//析构函数 String& operator=(const String &str);//赋值构造函数private: char *m_data;};
当用一个已初始化的类类型对象初始化一个新的对象时,拷贝构造函数就会被调用,拷贝构造函数会出现在以下三种情景:
1) 一个对象以值传递的方式传入函数体
void InputString(String obj){ //函数具体逻辑}
2) 一个对象以值传递的方式从函数返回
String OutputString(){ return String("hello world");}
3) 使用一个对象初始化另一个对象
String a(1);String b = a;//通过对象a初始化对象b
2、深拷贝和浅拷贝的区别
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
当用户没有自定义拷贝构造函数时,编译器会自动生成一个默认的拷贝构造函数,并以位拷贝(位拷贝就是浅拷贝)的方式完成对象之间的赋值。关于深拷贝和浅拷贝的一个经典例子就是String类的实现,以下代码使用一个String类对象初始化另一个String类对象:
String a("Shallow Copy");String b = a;
若上面的代码没有重写拷贝构造函数,就会出现以下的问题:
1) 对象a和对象b的成员变量m_data将会指向了同一内存区域,其中一方的改变将会影响另一方;
2) 当对象析构的时候,对象a的成员变量m_data将会被析构两次,造成程序崩溃。
3、拷贝构造函数和赋值构造函数
所谓赋值构造函数,就是操作符"="的重载函数,它的作用与拷贝构造函数类似,若没有重写赋值构造函数,编译器也会自动生成一个默认的以位拷贝工作的赋值构造函数。
String a("hello");String b("world");b = a;
若上面的代码没有重写赋值构造函数,则会出现以下问题:
1) 对象b的成员变量m_data原来指向的内存区域没有被释放,造成内存泄露;
2) 对象a和对象b的成员变量m_data将会指向了同一内存区域,其中一方的改变将会影响另一方
3) 当对象析构的时候,对象a的成员变量m_data将会被析构两次,造成程序崩溃。
不是说有等于号的时候就是赋值构造函数,有的时候拷贝构造函数和赋值构造函数容易混淆,看以下例子:
String a("hello");String b("world");String d = a;//拷贝构造函数b = a;//赋值构造函数
当用一个已存在的对象初始化一个未存在的对象时,调用的是拷贝构造函数;当用一个已存在的对象给另一个已存在的对象赋值时,调用的是赋值构造函数,它也仅出现在这种情况。
为了设计出更安全的类,需要使用到拷贝构造函数和赋值构造函数时,则重写一个深拷贝的版本;若不需要,则禁用这两个函数,免得出现一些不应该的错误。只要对拷贝构造函数和赋值构造函数的函数访问级别设置为private即可以禁用这两个函数,以前面的String简单定义代码为例子:
class String{public: String(const char *ch=NULL);//默认构造函数~String(void);//析构函数private: String(const String &str);//拷贝构造函数 String& operator=(const String &str);//赋值构造函数private: char *m_data;};
- C++之一些事一些情--深拷贝和浅拷贝
- Object-c 深拷贝和浅拷贝
- [Objective-C]浅拷贝和深拷贝
- 【C++】深拷贝和浅拷贝
- 【C++】深拷贝和浅拷贝
- Objective-C浅拷贝和深拷贝
- 【C++】深拷贝和浅拷贝解析
- C中的深拷贝和浅拷贝
- [c++]深拷贝和浅拷贝
- 【C++】深拷贝、浅拷贝和写时拷贝
- C++之浅拷贝和深拷贝
- Python之深拷贝和浅拷贝
- c++之浅拷贝和深拷贝
- C++之 浅拷贝和深拷贝
- c++之浅拷贝和深拷贝
- JavaScript之浅拷贝和深拷贝
- javascript之深拷贝和浅拷贝
- C++之 深拷贝和浅拷贝
- 物理卷、卷组、逻辑卷、硬盘分区等概念介绍
- NYOJ 13 Fibonacci数
- java基础
- linux压缩解压命令
- FZU2138-久违的月赛之一
- C++之一些事一些情--深拷贝和浅拷贝
- Java基础笔记 – 面向对象三个特征 继承、封装、多态及编程细节提示
- springMVC可以进入controller,jsp读取c标签无法读取值,直接显示${userList},
- 使用Tomcat插件开发WEB应用
- eclipse常用快捷键介绍
- C++之一些事一些情--虚析构函数
- fedora 遇到“another app is currently holding the yum lock;waiting for it to exit”问题
- NIO与普通IO文件读写性能对比
- MFC中运行出现问题“不支持尝试执行的操作”