虽然以前做过更复杂的各种数据结构,不过那只是在看完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. apache基本安装配置

    1.安装apache 1.安装 wget http://mirrors.cnnic.cn/apache//httpd/httpd-2.2.31.tar.gz 2.安装zlib yum install ...

  2. Android LayoutInflater.inflate使用上的问题解惑

    最近在在使用LayoutInflater.inflate方法时遇到了一些问题,以前没有仔细看过此类的使用方法,故将其记录下来,方便日后查阅. 相信大家都知道LayoutInflater.inflate ...

  3. 泛型集合List<T> Dictionary<K,V>

    List<T>类似于ArrayList,ArrayList的升级版. 各种方法:Sort().Max().Min().Sum()…   Dictionary<K,V>类似于Ha ...

  4. mysqli扩展库操作mysql数据库

    配置环境 配置php.ini文件让php支持mysqli扩展库 extension=php_mysqli.dll 建库建表 详见博客 “mysql扩展库操作mysql数据库” 查询数据库 <?p ...

  5. sqlsever2008数据库的备份与还原

    本文数据库的名称为ProjectControl  public static SqlConnection conn = new SqlConnection("server=(local);u ...

  6. SortedList的用法

    1.SortedList定义 System.Collections.SortedList类表示键/值对的集合,这些键值对按键排序并可按照键和索引访问.SortedList 在内部维护两个数组以存储列表 ...

  7. 2015年9月29日 sql 触发器

    触发器(trigger):当有关联操作的时候使用(级联操作),属于ddl关键字. eg:下订单时,创建中的商品数量要减少:退票时,总的票数要增加.         在订单上建立触发器         ...

  8. nvarchar类型自动增长

    ,Col AS 'XH' + RIGHT('0000' + RTRIM(ID),4)

  9. PHP获得文件的md5并检验是否被修改

    由于需要判断上传的文件是否被修改过,需要记录上传文件的md5值,所以这里说一下一下获取文件md5值的方法.   md5_file() md5_file() 函数计算文件的 MD5 散列.md5() 函 ...

  10. [mock]10月4日

    第一次mock,CollabEdit开一个页面,开始做题.题目是,有方法pow(m,n),m和n都大于1,给出N,有顺序的打印出前N个pow(m,n)的结果.前一个是:4,8,9,16,... 然后在 ...