博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
写时复制
阅读量:4463 次
发布时间:2019-06-08

本文共 4629 字,大约阅读时间需要 15 分钟。

概念:在有些大型类中复制一个类要花费大量时间。

TString one("abcd");

TString two(one);

这时写时复制就可以解决这个问题,所有复制对象共用原对象,当要改变对象的数据成员时才产生一个新的副本。

 

 .head

1 #pragma once 2 #include
3 #include
4 #include
5 #include
6 using namespace std; 7 8 class TString 9 {10 public:11 //输入/输出操作符12 //构造函数,创建一个空字符对象13 TString();14 //创建一个字符串对象,该对象包含指向字符的s指针15 //s必须以NULL结尾,从s中复制字符16 TString(const char* s);17 //创建一个包含单个字符aChar的字符串18 TString(char aChar);19 TString(const TString& arg);//拷贝构造函数20 ~TString();//析构函数21 //赋值操作符22 TString& operator=(const TString& arg);23 TString& operator=(const char* s);24 TString& operator=(char aChar);25 //返回对象当前储存的字符个数26 int Size() const;27 //返回posn中len长度的子字符串28 TString operator()(unsigned posn, unsigned len) const;29 //返回下表为n的字符30 char operator()(unsigned n) const;31 //返回对下标为n的字符的引用32 const char& operator[](unsigned n) const;33 //返回指向内部数据的指针,当心34 const char* c_str()const { return _str; };35 //以下方法将修改原始对象。36 //把其他对象中的字符附加在*this后37 TString& operator+=(const TString& other);38 //在字符串中改动字符的情况39 TString& ToLower();//将大写字符转换成小写40 TString& ToUpper();//将小写字符转换成大写41 private:42 struct StringRep43 {44 char *_str;//实际的字符45 unsigned _refCount;//对它的引用的数目46 unsigned _length;//字符串中的字符数目47 };48 StringRep *_rp; //再TString中唯一的数据成员;49 50 };51 52 //支持TString类的非成员函数53 //返回一个新TSring类的对象,该对象为one和two的级联54 TString operator+(const TString& one, const TString& two);55 //输入/输出操作符56 ostream& operator<<(ostream& o, const TString& s);57 istream& operator >> (istream& stream, TString& s);58 //关系操作符,基于ASCII字符集比较。59 //如果两字符串对象包含相同的字符,则两对象相等。60 bool operator==(const TString& first, const TString& second);61 bool operator!=(const TString& first, const TString& second);62 bool operator<(const TString& first, const TString& second);63 bool operator>(const TString& first, const TString& second);64 bool operator>=(const TString& first, const TString& second);65 bool operator<=(const TString& first, const TString& second);

.cpp;

1 #include "TString.h"  2   3   4   5 TString::TString()  6 {  7     _rp = new StringRep;  8     _rp->_refCount = 1;  9     _rp->_length = 0; 10     _rp->_str = 0; 11 } 12  13  14 TString::TString(const char* s) 15 { 16     _rp = new StringRep; 17     _rp->_refCount = 1; 18     _rp->_length = strlen(s); 19     _rp->_str = new char[_rp->_length + 1]; 20     strcpy(_rp->_str, s); 21 } 22  23 TString::TString(char aChar) 24 { 25     _rp = new StringRep; 26     _rp->_refCount = 1; 27     _rp->_length = 1; 28     _rp->_str = new char[_rp->_length + 1]; 29     _rp->_str[0] = aChar; 30     _rp->_str[1] = 0; 31 } 32  33  34 TString::TString(const TString& other) 35 { 36     //这时重要的操作之一; 37     //我们需要再other中,通过_rp所指向的对象递增引用计数。它又获得一个引用。 38     other._rp->_refCount++; 39     //让它们共享资源 40     this->_rp = other._rp; 41 } 42  43 TString& TString::operator=(const TString& other) 44 { 45     if (this == &other) 46         return *this;//自我赋值 47     /*这时另一个重要的操作。我们需要再other中,通过_rp所指向的对象递增引用计数。 48     同时,需要用过this指向的对象递减引用计数*/ 49     other._rp->_refCount++; //它又获得一个引用 50     //递减和测试,是否仍然再使用它 51     if (--this->_rp->_refCount == 0) 52     { 53         delete[]this->_rp->_str; 54         delete this->_rp; 55     } 56     this->_rp = other._rp;//共享资源; 57     return *this; 58  59 } 60  61  62  63 //这是一个重要的成员函数,需要应用“写时复制”方案 64 TString& TString::ToLower() 65 { 66     char *p; 67     if (_rp->_refCount > 1) 68     { 69         //这是最困难的部分。分离TString对象并提供它的StringRep对象; 70         //这是“写时复制”操作 71         unsigned len = this->_rp->_length;//保存它 72         p = new char[len + 1]; 73         strcpy(p, this->_rp->_str); 74         this->_rp->_refCount--;//因为*this即将离开内存池; 75         this->_rp = new StringRep; 76         this->_rp->_refCount = 1; 77         this->_rp->_length = len; 78         this->_rp->_str = p;//p在前面已创建 79     } 80  81     //继续,并改变字符 82     p = this->_rp->_str; 83     if (p != 0) 84     { 85         while (*p) 86         { 87             *p = tolower(*p); 88             ++p; 89         } 90     } 91     return *this; 92 } 93  94 TString& TString::ToUpper()//和tolower的相似方法 95 { 96     return *this; 97 } 98  99 100 101 TString::~TString()102 {103     if (--_rp->_refCount == 0)104     {105         delete[] _rp->_str;106         delete _rp;107     }108 }109 110 //省略其他函数的实现;

思考:在上面的代码中,很多地方都需要创建、删除和操控StringRep对象。很明显,这并不是最好的方法。尝试修改实现,以便StringRep有自己的构造

函数、析构函数以及其他函数。这样,StringRep便可自我管理。另外,完成TString类的实现;

转载于:https://www.cnblogs.com/zhengzhe/p/6542854.html

你可能感兴趣的文章
面试题:比较两个数字大小
查看>>
Linux命令:pgrep
查看>>
大数据应用期末总评
查看>>
Windows Store App之数据存储
查看>>
实验五:Xen环境下多虚拟机的桥接配置
查看>>
抽象类和开闭原则
查看>>
English class 82 The Importance of traveling
查看>>
C++ 类与对象
查看>>
python用递归函数解汉诺塔游戏
查看>>
可持久化线段树入门小结
查看>>
Redis与Python交互
查看>>
VueJS参数绑定:v-bind:href,v-on:event
查看>>
Jmeter进行接口测试
查看>>
第一天python学习内容
查看>>
Maximum-SubsequenceSum
查看>>
常用的一些shell变量
查看>>
IOS省电
查看>>
Android无法删除项目+导入项目报错
查看>>
【python】获取网页中中文内容并分词
查看>>
每周进度条(第14周)
查看>>