String写时拷贝实现
头文件部分
1 /*
版权信息:狼
文件名称:String.h
文件标识:
摘 要:对于上版本简易的String进行优化跟进。
改进
1.(将小块内存问题与大块分别对待)小内存块每个对象都有,当内存需求大于定义大小时利用动态分配
2.实现大块内存的写时拷贝功能,提高效率,优化空间利用
3.类似new[]实现机制:将动态内存块大小信息保存为隐藏“头” 当前版本:1.2
修 改 者:狼
完成日期:2015-12-12 取代版本:1.1
原 作 者:狼
完成日期:2015-12-11
*/
#ifndef _STRING_H
#define _STRING_H
#include<iostream>
using namespace ::std; namespace COW
{
class String
{
friend void Check_Interface(String &S);
friend ostream& operator << (ostream&os, String &Str); public:
String(const char* str = "");
String(String& Str);
String& operator=(const String& Str);
~String(); private:
void decrease();//减少引用计数。
void increase();//增加引用计数。 private:
enum{BufSize = }; //利用枚举进行数组初始化
char *_str; //内容块,“头”代替capacity
char _buff[BufSize]; //小内存块处理。
};
ostream& operator << (ostream&os, String &Str);
}
#endif
///////////////实现文件
#include"String.h"
#pragma warning (disable:4351 4996) using namespace COW; String::String(const char *Str)
:_str(NULL)
, _buff()
{
//采用动态分配
if (strlen(Str) >= BufSize)
{
_str = new char[strlen(Str) + ]; *((int*)_str) = ; strcpy(_str + , Str);
}
else//栈内存储
{
strcpy(_buff, Str);
}
}
String::String(String& Str)
:_str(NULL)
, _buff()
{
// 1.如果是小块内存。浅拷贝
if (Str._str == NULL)
{
strcpy(_buff,Str._buff);
}
else
{
_str = Str._str;
this->increase();
}
}
String& String::operator=(const String& Str)
{
//都是动态 且指向一处
if (_str == Str._str&&_str != NULL)
return *this; //两个都是小内存时
if (Str._str == NULL&&_str==NULL)
{
strcpy(_buff, Str._buff);
}
//如果*this 是小内存(不存在内存变更,不用处理buff),Str 动态。
else if (_str==NULL&&Str._str!=NULL)
{
_str = Str._str;
this->increase();
} //*this 动态,Str小内存。减少*this._str计数。。.更改buff
else if(_str!=NULL&&Str._str==NULL)
{
this->decrease();
_str = NULL;
strcpy(_buff,Str._buff);
} //两个都是动态分配 但不同
else
{
this->decrease();
_str = Str._str;
this->increase();
}
return *this;
}
void String::increase()
{
*(int*)_str += ;
}
void String::decrease()
{
if (_str != NULL)
{ //////问题2,,每次decrease之后必须变更_str..为NULL或者指向新块
if ((*(int*)_str) - != )
{
(*(int*)_str) -= ;
}
else
{
delete[]_str;
_str = NULL;
}
}
}
String::~String()
{
this->decrease();
_str = NULL;
} ///////问题1...命名空间冲突时
ostream& COW::operator << (ostream&os, String &Str)
{
if (Str._str)
{
os << (Str._str + ) << "\t"<< (*(int*)Str._str);
}
else
os << Str._buff;
return os;
}
//////friend 友员函数不能跨越命名空间访问私有成员????????????
//void Check_Interface(COW::String &S)
//{
// //char COW::String::*ch = S._str;
// char *ch = S._str;
// cout << endl;
//}
/////////////测试模块
#include"String.h"
using namespace COW; void Test_COPY_EPU()
{ String S1("hellow world!");
String S2("hellow world");
String S3;
S3 = S2;
String S4;
S4 = S1;
//少对多,少对少
cout << "小内存赋值" << S3 << endl;
cout << "小内存赋值" << S4 << endl; //多对多,多对少
String S5("change world");
S5 = S1;
cout << S5 << endl;
S5 = S2;
cout << S5 << endl;
//多多且等
String S6 = S1;
S6 = S1;
cout << S6 << endl;
}
void main()
{
Test_COPY_EPU();
}

String写时拷贝实现的更多相关文章
- 转C++之stl::string写时拷贝导致的问题
前几天在开发某些数据结构到文件的 Dump 和 Load 功能的时候, 遇到的一个 bug . [问题复现] 问题主要出在 Load 过程中,从文件读取数据的时候, 直接使用 fread 的去操作 s ...
- String类的实现(4)写时拷贝浅析
由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间.这种方法就是写时拷贝.这也是一种 ...
- 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
标准C++类std::string的内存共享,值得体会: 详见大牛:https://www.douban.com/group/topic/19621165/ 顾名思义,内存共享,就是两个乃至更多的对象 ...
- String 类的实现(2)引用计数与写时拷贝
1.引用计数 我们知道在C++中动态开辟空间时是用字符new和delete的.其中使用new test[N]方式开辟空间时实际上是开辟了(N*sizeof(test)+4)字节的空间.如图示其中保存N ...
- Linux写时拷贝技术(copy-on-write)
COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内 ...
- 【转】Linux写时拷贝技术(copy-on-write)
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...
- 计算机程序的思维逻辑 (73) - 并发容器 - 写时拷贝的List和Set
本节以及接下来的几节,我们探讨Java并发包中的容器类.本节先介绍两个简单的类CopyOnWriteArrayList和CopyOnWriteArraySet,讨论它们的用法和实现原理.它们的用法比较 ...
- 并发容器之写时拷贝的 List 和 Set
对于一个对象来说,我们为了保证它的并发性,通常会选择使用声明式加锁方式交由我们的 Java 虚拟机来完成自动的加锁和释放锁的操作,例如我们的 synchronized.也会选择使用显式锁机制来主动的控 ...
- 深拷贝&浅拷贝&引用计数&写时拷贝
(1).浅拷贝: class String { public: String(const char* str="") :_str(]) { strcpy(_str,str); } ...
随机推荐
- Oracle 性能调优 10053事件
思维导图 10053事件概述 我们在查看一条SQL语句的执行计划时,只看到了CBO最终告诉我们的执行计划结果,但是我们并不知道CBO为何要这样做. 特别是当执行计划明显失真时,我们特别想搞清楚为什么C ...
- Ajax 报错 500 (Internal Server Error)
==========error======={"readyState":4,"responseText":"<html><head& ...
- vue生命周期探究(二)
vue生命周期探究(二) 转载自:https://segmentfault.com/a/1190000008923105 上一章我们介绍了vue的组件生命周期和路由勾子,这一章,让我们来看看在vue- ...
- hdp (ambari) 集成hue
ambari-server resetambari-admin-password-reset https://github.com/EsharEditor/ambari-hue-service可以基于 ...
- Java线程的几个概念
线程的生命周期: 新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 就绪状态:当一个线程创建了以后,其他的线程调用了它的start()方法,该线 ...
- 使用Node.js快速搭建简单的静态文件服务器
做前端有时会采用一些复杂框架,在文件系统中直接打开页面(用file:///方式打开),往往会报跨域的错,类似于“XMLHttpRequest cannot load ...(文件名). Cross o ...
- iOS开发之plist文件操作
之前在想用代码去实现很多界面上能用interface builder可以拖进去的功能,现在想想真是够无知的啊.不仅效率低下,而且对于代码的维护带来不少麻烦,这段时间一直在反思看了design+code ...
- 服务器抓包命令:tcpdump详解
官网地址:http://www.tcpdump.org/tcpdump_man.html 简介: tcpdump,就是:dump the traffic on a network,根据使用者的定义对网 ...
- SQL学习笔记之MySQL查询的三层解析
Mysqld的三层结构: SQL类型: DDL:数据库对象定义语言 对库和表的定义 DML:操作语言 DCL:控制语言 结构化的查询语言:select * from user; 执行该语句时: 1.连 ...
- 【ES6】改变 JS 内置行为的代理与反射
代理(Proxy)可以拦截并改变 JS 引擎的底层操作,如数据读取.属性定义.函数构造等一系列操作.ES6 通过对这些底层内置对象的代理陷阱和反射函数,让开发者能进一步接近 JS 引擎的能力. 一.代 ...