虽然以前做过更复杂的各种数据结构,不过那只是在看完c++prime7章后做的,没有考虑到类的拷贝体现出来是类值还是类指针,于是写了一些半成品类,不过那些主要是练数据结构,不想再改,于是就想办法模仿了下string,以前都是使用new和delete,虽然简单,但是不够灵活,于是就刻意使用alloctor模板来管理内存,这样可以将“内存分配”与“对象构造分开”,因为对象并不是指针这类管理外部资源的对象,于是我就干脆不destory,这样使用alloctor效率优势更加有体现,练下手熟,总的来说没什么难度。

#include <iostream>
#include <string>
#include <memory>
using namespace std;
const int incerment=;
class String{
public:
friend istream& operator >> (istream &is, const String &s);
friend ostream& operator << (ostream &os, const String &s);
friend const String operator + (const String& a,const String& b);
String() :elements(nullptr), last_element(nullptr), space_end(nullptr){}
String(const char *s) :String(){
for (size_t i = ; s[i]; i++)
push_back(s[i]);
}
String(const String &s) :elements(nullptr), last_element(nullptr), space_end(nullptr){
elements = alloc.allocate(s.size() * );
last_element = uninitialized_copy(s.begin(), s.end(), elements);
space_end = elements + s.size() * ;
uninitialized_fill(last_element, space_end, );
}
String(const size_t &len) :elements(nullptr), last_element(nullptr), space_end(nullptr){
elements = alloc.allocate(len);
uninitialized_fill_n(elements, len, );
last_element = elements;
space_end = elements + len;
}
String(char *b, char *e):String(){
auto p = b;
while (p != e){
push_back(*p++);
}
}
String(size_t n, char ch):String(){
elements = alloc.allocate(n*);
uninitialized_fill_n(elements, n, ch);
last_element = elements + n;
space_end = elements + n * ;
}
~String(){
alloc.deallocate(elements, capcity());
};
void swap(String &a, String &b){
using std::swap;
swap(a.elements, b.elements);
swap(a.last_element, b.last_element);
swap(a.space_end, b.space_end);
}
void clear(){
alloc.deallocate(elements, capcity());
elements = last_element = space_end = nullptr;
}
void push_back(char ch){
if (size() >= capcity()){
auto newcap = capcity() + incerment;
auto p = alloc.allocate(newcap);
if (elements)
last_element = uninitialized_copy(elements, last_element, p);
else{
elements = last_element = p;
}
space_end = elements + newcap;
uninitialized_fill(last_element, space_end, );
}
*last_element++ = ch;
}
String& operator = (String s){
swap(*this, s);
return *this;
}
char &operator [] (const size_t i){
return elements[i];
}
const char& operator [] (const size_t i)const{
return elements[i];
}
bool operator == (const String &s)const{
if (size() != s.size())
return false;
for (size_t i = ;elements+i!=last_element;i++)if(elements[i]!=s[i]){
return false;
}
return true;
}
bool operator != (const String &s)const{
return !(equal(elements, last_element, s.begin()));
}
String& operator += (const String& s){
auto newcap = capcity() + s.capcity();
auto p = alloc.allocate(newcap);
uninitialized_copy(elements, last_element, p);
last_element = uninitialized_copy(s.begin(), s.last_element, p + size());
alloc.deallocate(elements,capcity());
elements = p;
space_end = elements + newcap;
uninitialized_fill(last_element,space_end,);
return *this;
}
size_t size()const{ return last_element-elements; }
size_t capcity()const{ return space_end - elements; }
char*begin()const{return elements;}
char *end()const{ return last_element; } private:
allocator<char> alloc;
char *elements,*last_element,*space_end;
};
istream& operator >> (istream &is,String &s){
char buf;
while (is>>buf){
s.push_back(buf);
}
return is;
}
ostream&operator << (ostream&os, const String&s){
auto p = s.begin();
while (p != s.end()){
os << *p++;
}
return os;
}
const String operator + (const String& a, const String& b){
shared_ptr<String> res=make_shared<String>(a);
*res += b;
return *res;
}
int main(){
{
String a("a"), b = "b",c;
cout << "a = " << a << " b = " << b << " c == " << c << endl;
c = b;
puts(c == b ? "Yes" : "No");
cout << "a = " << a << " b = " << b << " c == " << c << endl;
a += b;
cout << "a = " << a << " b = " << b << " c == " << c << endl;
c = "c";
puts(c == b ? "Yes" : "No");
cout << "a = " << a << " b = " << b << " c == " << c << endl;
c += "d";
cout << "a = " << a << " b = " << b << " c == " << c << endl;
b = a + c;
cout << "a = " << a << " b = " << b << " c == " << c << endl;
String d(b.begin()+,b.end()), e(,'e'),f="f"+e;
cout << "e.capcity = " << e.capcity() <<" d = "<<d<<" e = "<<e<< endl;
f += 'g';
cout << "a = " << a << " b = " << b << " c == " << c << endl;
String h = "h";
h = b + h;
cout << h[] <<" "<< h[h.size() - ];
}
_CrtDumpMemoryLeaks();
}

使用alloctor模板来实现string类的更多相关文章

  1. C++——string类和标准模板库

    一.string类 1.构造函数 string实际上是basic_string<char>的一个typedef,同时省略了与内存管理相关的参数.size_type是一个依赖于实现的整型,是 ...

  2. 《C++ Primer Plus》第16章 string类和标准模板库 学习笔记

    C++提供了一组功能强大的库,这些库提供了很多常见编程问题的解决方案以及简化其他问题的工具string类为将字符串作为对象来处理提供了一种方便的方法.string类提供了自动内存管理动能以及众多处理字 ...

  3. C++标准模板库Stand Template Library(STL)简介与STL string类

    参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进 ...

  4. C++ primer plus读书笔记——第16章 string类和标准模板库

    第16章 string类和标准模板库 1. string容易被忽略的构造函数: string(size_type n, char c)长度为n,每个字母都为c string(const string ...

  5. 面向对象(类,实例变量,方法定义,方法重载,构造方法,this,string类)

    面向对象 类是由属性和方法组成 类是所有创建对象的模板 实例变量有默认值 实例变量至少在本类范围中有效 实例变量与局部变量冲突时,局部变量优先 类中方法定义类似于函数定义 修饰符 返回值类型 方法名( ...

  6. C++:string类的使用

    类 <string> std::string String类的定义 , 其也是个模板类 typedef basic_string<char> string; String cl ...

  7. (转)C++——std::string类的引用计数

    1.概念 Scott Meyers在<More Effective C++>中举了个例子,不知你是否还记得?在你还在上学的时候,你的父母要你不要看电视,而去复习功课,于是你把自己关在房间里 ...

  8. C++string类总结

    一.string的初始化 首先,为了在程序中使用string类型,必须包含头文件 <string>.如下: #include <string> 注意这里不是string.h,s ...

  9. 【C++】C++string类总结

    一.string的初始化 首先,为了在程序中使用string类型,必须包含头文件 <string>.如下: #include <string> 注意这里不是string.h,s ...

随机推荐

  1. shell脚本操作mysql数据库—创建数据库,在该数据库中创建表(插入,查询,更新,删除操作也可以做)

    #!/bin/bash HOSTNAME="192.168.1.224"                                           #数据库Server信 ...

  2. 青瓷qici - H5小游戏 抽奖机 2 界面布局

    背景图片 首先我们需要在当前场景下面创建UI的根节点,这个根节点决定了我们整个游戏的元素布局,以及适应多分辨率的缩放布局问题,所以我们其他的元素都要放在UIRoot下面. 考虑到我自己测试的时候在PC ...

  3. xml之phpdom操作

    php xml编程XML解析技术介绍 1.php与DOM 2.PHP与XPath 3.SimpleXML DOM(document object model)文档对象模型 把一个文件看做一个对象模型, ...

  4. PHP通过(PDO)Mysql表字段一键生成创建sqlite的SQL

    首发于:http://www.zzzzy.com/201406053158.html /** * Mysql表字段一键生成创建sqlite的SQL 2 * @author: Skiychan < ...

  5. Groovy 数组操作

    将字符串转为map def str="['汤菜':['1000000028','1000000030'],'肉菜':['1000000032'],'素材':['1000000031']]&q ...

  6. 查看文章 mysql:表注释和字段注释[转]

    1 创建表的时候写注释 create table test1 ( field_name int comment '字段的注释' )comment='表的注释'; 2 修改表的注释 alter tabl ...

  7. 基于类和redis的监控系统开发

    最近学习python运维开发,编写得一个简单的监控系统,现记录如下,仅供学习参考. 整个程序分为7个部分: 第一个部分根据监控架构设计文档架构如下: .├── m_client│   ├── conf ...

  8. Hadoop中的RPC

    基于hadoop2.6.4,RPC相关的实现位于hadoop-common这个project中hadoop-common-project/hadoop-common/src/main/java的包pa ...

  9. csu 10月 月赛 B 题 Scoop water

    一个卡特兰数的应用: 卡特兰数主要有以下几个用途: 1.不同的出栈入栈数: 2.n个点组成的不同的二叉树的数目: 3.凸多边形的三角剖分划分: 4.括号化问题: 通项公式是:h(n) = C(2n-2 ...

  10. JAVA与编译语言及解释语言的关系

    转自JAVA结合了编译和解释执行的优点 编译型语言是一次性编译成机器码,脱离开发环境独立运行,所以运行效率较高,但是由于编译成的是特定平台上机器码,所以可移植性差. 编译型语言的典型代表有C.C++. ...