C++String深浅拷贝
来源:互联网 发布:ubuntu 16.04 编辑:程序博客网 时间:2024/04/30 00:28
C++的一个类里面有6个默认成员函数,意味着如果我们自己不定义这六个函数,那么编译器会使用系统的成员函数,但是一旦我们自己定义了这六个成员函数,那么编译器会调用我们定义的,而不是系统默认的,现在我们主要来分析以下String的深浅拷贝问题。深浅拷贝是C++中比较重要的。
什么是浅拷贝
所谓的浅拷贝,就是只拷贝指针指向的内容,而不改变它的地址空间,这就意味着改变其中一个的内容,另一个也跟着改变。
示例:
class String{public: String(char *str='\0') //构造函数 { _str = new char[strlen(str)+1]; strcpy(_str, str); } String& operator=(const String& s); ~String() { if(_str) { delete[]_str; _str = NULL; } }private: char *_str;};
这里解释一下为什么构造函数缺省传参不传NULL而是‘\0’,其实想一下就知道了,如果我们传NULL,在后面的拷贝构造函数中难免用到它,一旦我们传了一个空指针过去,那么在这里就会出错,因此我们缺省传参传‘\0’,因为C中字符串以\0结尾,这里为了兼容C,因此传参传了一个\0。
我们看看浅拷贝的情况:
void Test(){ String s1("hello world"); String s2(s1);}
通过调试看看他们的存储情况
通过调试我们可以看到他们的内存位置,内容都是相同的,改变其中一个另一个也会随之改变,这就是浅拷贝。浅拷贝在我们析构的时候会带来很多问题,因为在一个对象生命周期结束之后就会调用析构函数,因此这就会导致内存泄露等问题,因此我们有了深拷贝。
深拷贝问题
深拷贝,就是拷贝的时候会另外申请一块空间,然后拷贝内容,对其中一块空间进行操作不会影响另一块空间。
深拷贝我们有两种方法:
(1)传统方法:老老实实进行申请空间,然后拷贝。
(2)现代方法:简单来说就是拿来主义,在别人开辟好空间,拷贝好数据,然后我们只需要拿过来就可以了。
(1)传统方法:
String& String::operator=(const String& s){ if(_str != s._str) { delete []_str; //释放原空间 _str = new char[strlen(s._str)+1];//申请内存 strcpy(_str, s._str);//拷贝 } return *this;}
(2)现代方法:
//拷贝构造String(const String& s):_str(NULL) //思考一下为什么需要初始化为NULL??{ String tmp(s); swap(_str, tmp._str);}//赋值运算符重载String& String::operator=(String s){ if(_str != s.str) { String tmp(s); //创建一个临时变量进行拷贝 swap(_str, tmp._str);// 交换数据 }return *this;}
思考:
为什么需要在拷贝构造的时候初始化_str为NULL,而重载不需要?
因为创建的tmp为临时空间,出了作用域后会被销毁,销毁后_str为野指针1,这是会导致最后的析构出错,因此需要赋初值为NULL。
在重载的时候创建的tmp也是一个临时变量,出了作用域后会调用析构函数,因为我们本来的意愿就是要释放这块空间,因此我们不用初始化。
现代方法与传统方法比较
现代方法更加简洁,在我们使用的时候通常两种配合着使用。
- C++String深浅拷贝
- C++String深浅拷贝问题
- c++-----string和深浅拷贝
- C++String深浅拷贝、写时拷贝
- string--深浅拷贝
- Objective-c 深浅拷贝
- 【C++】 浅析深浅拷贝
- String类与深浅拷贝
- 深浅拷贝(String类)
- Objective-C 深浅拷贝学习
- [解析]Objective-C 深浅拷贝
- 浅析Objective-C 深浅拷贝
- string类的深浅拷贝问题
- string的深浅拷贝以及写时拷贝问题
- ios&object-c深浅拷贝解析
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 【Spring】事务(transactional)之初步理解
- hibernate入门的基本配置
- CentOS安装mysql数据库
- Leetcode 461.Hamming Distance
- Kotlin-33.异常(Exception)
- C++String深浅拷贝
- 项目中使用Bootstrap以及基于bootstrap的 Bootgrid
- fatal: unable to access 'url': Failed connect to githup.com:443; No error
- 523. Continuous Subarray Sum
- Leetcode 561.Array Partition I
- IAR STM32 函数和变量的绝对地址定位
- 区别
- webstorm常用快捷键
- 湖南省第十二届大学生计算机程序设计竞赛 Parenthesis