string类之深拷贝的两种写法
2016-06-06 22:48
337 查看
1 第一种就是普通写法,需要强调的地方不多,代码中有关地方已经给出注释
2 简洁版的深拷贝 这是重点要掌握的
在这个版本中,构造函数和析构函数并没有改变,改变的是复制运算符重载,拷贝构造
先看这段实现代码
看起来这段代码并没有问题,但是运行起来会崩溃
仔细分析一下是因为p没有具体的指向,但是我们却用它和另一个指针交换所指向的内容,我们使用的这个p此时是野指针.
因此在初始化列表里应该将他置空,此时再来交换就没有问题了
这就是深拷贝的简洁版,直接交换俩个指针的指向,易于理解且写起来不易出错
/*#include<iostream> using namespace std; # class String { public: //这是系统默认的 String()//这是先给pstr开辟一个空间来存放'\0',注意'\0'的写法 :p(new char[1]) { *p = '\0';\ } //显示的给出 开辟空间时候加1是为了放'\0' //也可以合起来写 改成String(char*p="") String(char *pstr) :p(new char[strlen(pstr)+1]) { if (pstr == NULL) { p = new char[1]; *p = '\0'; } else { p = new char[strlen(pstr) + 1]; strcpy(p, pstr); } } 拷贝构造函数 String(const String &s) { p = new char[strlen(s.p) + 1]; strcpy(p, s.p); } //赋值运算符重载 //注意四个问题 //1)返回值 //2)参数 //3)检测其是否给自身赋值 //4)返回为*this String & operator = (const String &s) { if (this != &s) { char *tmp = new char[strlen(s.p) + 1]; strcpy(tmp, s.p); delete []p; p = tmp; } return *this; } //析构函数 ~String() { if (p) { delete[] p; } } private: char *p; }; int main() { String s1; String s2("aaa"); String s = s2; String s3(s2); s2 = s1; return 0; }*/
2 简洁版的深拷贝 这是重点要掌握的
在这个版本中,构造函数和析构函数并没有改变,改变的是复制运算符重载,拷贝构造
先看这段实现代码
String(const String &s) { String tmp(s.p); std::swap(p, tmp.p); } //赋值运算符重载 /*String &operator=( String s) { std::swap(p, s.p); return *this; }*/ //另一种写法 String & operator=(const String &s) { if ( this != &s) { String tmp(s.p); std::swap(p, tmp.p); } return *this; }
看起来这段代码并没有问题,但是运行起来会崩溃
仔细分析一下是因为p没有具体的指向,但是我们却用它和另一个指针交换所指向的内容,我们使用的这个p此时是野指针.
因此在初始化列表里应该将他置空,此时再来交换就没有问题了
这就是深拷贝的简洁版,直接交换俩个指针的指向,易于理解且写起来不易出错
相关文章推荐
- 正则判断是不是手机号码&复制文件工具类&SharedPreferencesUtils工具类
- Zookeeper应用的场景
- php +mysql 留言板
- 快速排序的实现
- java-Leetcode- Binary Tree Traversal
- 正则表达式详解
- linux下操作redis数据库的常用命令
- 编程0基础,自学成才
- 构建之法阅读笔记05
- PAT乙级—1050. 螺旋矩阵(25)-native
- UIview 和原生的交互处理
- rotate-image
- 《java入门第一季》之集合框架TreeSet存储元素自然排序以及图解
- VBS判断本地账户密码过期邮件提醒
- ViewPager的自带导航
- HttpClient4.X发送带参数的Get请求
- 二分查找 —— 从三分支到二分支
- 《java入门第一季》之集合框架TreeSet存储元素自然排序以及图解
- tweenMax学习笔记
- 《Linux课本》读书笔记 第十七章 模块