头文件部分
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写时拷贝实现的更多相关文章

  1. 转C++之stl::string写时拷贝导致的问题

    前几天在开发某些数据结构到文件的 Dump 和 Load 功能的时候, 遇到的一个 bug . [问题复现] 问题主要出在 Load 过程中,从文件读取数据的时候, 直接使用 fread 的去操作 s ...

  2. String类的实现(4)写时拷贝浅析

    由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间.这种方法就是写时拷贝.这也是一种 ...

  3. 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)

    标准C++类std::string的内存共享,值得体会: 详见大牛:https://www.douban.com/group/topic/19621165/ 顾名思义,内存共享,就是两个乃至更多的对象 ...

  4. String 类的实现(2)引用计数与写时拷贝

    1.引用计数 我们知道在C++中动态开辟空间时是用字符new和delete的.其中使用new test[N]方式开辟空间时实际上是开辟了(N*sizeof(test)+4)字节的空间.如图示其中保存N ...

  5. Linux写时拷贝技术(copy-on-write)

    COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内 ...

  6. 【转】Linux写时拷贝技术(copy-on-write)

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...

  7. 计算机程序的思维逻辑 (73) - 并发容器 - 写时拷贝的List和Set

    本节以及接下来的几节,我们探讨Java并发包中的容器类.本节先介绍两个简单的类CopyOnWriteArrayList和CopyOnWriteArraySet,讨论它们的用法和实现原理.它们的用法比较 ...

  8. 并发容器之写时拷贝的 List 和 Set

    对于一个对象来说,我们为了保证它的并发性,通常会选择使用声明式加锁方式交由我们的 Java 虚拟机来完成自动的加锁和释放锁的操作,例如我们的 synchronized.也会选择使用显式锁机制来主动的控 ...

  9. 深拷贝&浅拷贝&引用计数&写时拷贝

    (1).浅拷贝: class String { public: String(const char* str="") :_str(]) { strcpy(_str,str); } ...

随机推荐

  1. 1141 PAT Ranking of Institutions[难]

    1141 PAT Ranking of Institutions (25 分) After each PAT, the PAT Center will announce the ranking of ...

  2. Appium-Java滑动操作

    Java滑动操作,通常可以直接使用API中AndroidDriver类中的swipe方法,直接进行调用 swipe(int startx, int starty, int endx, int endy ...

  3. RNNs

    什么是RNN网络? RNNs背后的主要目的是要使用序列本身的顺序信息.在传统的神经网络里,我们假设输入(输出)是条件独立的.但是,在许多任务里,这是个非常非常差的假设.如果你想预测一个序列中的下一个单 ...

  4. hust1010 The Minimum Length

    地址:http://acm.hust.edu.cn/problem/show/1010 题目: 1010 - The Minimum Length Time Limit: 1s Memory Limi ...

  5. 【PS技巧】创建2D对象的描边阴影

    在本场景中,怪物死亡掉落宝袋.所以在玩家眼里,宝袋是掉落在场景里,而不是像其他界面的UI元素,悬浮在场景上的. 所以,我们需要给宝袋添加阴影,增加它与场景之间的视觉过渡,比较简单的办法是使用阴影,正如 ...

  6. How can For each...

    Answer:   I understand the IEnumerator/IEnumerable methods and properties and also how they are inte ...

  7. error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1600”不匹配值“1700”

    原因:由于你使用了vs2012,相比较vs2010以及之前的vs为更高版本,致使msvc不兼容! 方法:在项目右键属性-配置属性-常规中,平台工具集选用为合适平台即可,我这里就选择 vs2010 (v ...

  8. 搭建Firekylin博客

    搭建步骤 1).安装 Node.js curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - yum - ...

  9. c++对txt文件的读取与写入

    转自:http://blog.csdn.net/lh3325251325/article/details/4761575 #include <iostream> #include < ...

  10. Django学习笔记之Queryset详解

    Django ORM用到三个类:Manager.QuerySet.Model.Manager定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类,定义自己 ...