虽然以前做过更复杂的各种数据结构,不过那只是在看完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. ASP.NET数据绑定控件

    数据绑定控件简介 数据绑定分为:数据源 和 数据绑定控件 两部分,数据绑定控件通过数据源来获得数据,通过数据源来隔离数据提供者和数据使用者,数据源有:SqlDataSource,AccessDataS ...

  2. mysql 存储引擎 myisam innodb 区别

    虽然MySQL里的存储引擎不只是MyISAM与InnoDB这两个,但常用的就是它俩了.可能有站长并未注意过MySQL的存储引擎,其实存储引擎也是数据库设计里的一大重要点,那么博客系统应该使用哪种存储引 ...

  3. SQLite Helper (C#) z

    http://www.codeproject.com/Articles/746191/SQLite-Helper-Csharp Introduction I have written a small ...

  4. 将yyyyMMdd HH:mm:ss格式的时间转换成时间类型

    DateTime.ParseExact(gmt_withdrawal, "yyyyMMddHHmmss", System.Globalization.CultureInfo.Cur ...

  5. Servlet高级应用---Servlet与缓存

    一]设置缓存文件的有效日期        重点方法:            HttpServletRequest类:                    1>String getRequest ...

  6. js 介绍

    createjs 工作内容:html5游戏开发岗位要求:1. 熟悉HTML5特性, 掌握canvas开发技能;2.能独立的搭建出易扩展,高效,强壮,通用的前端底层框架;3.熟悉常用的JS开发框架或工具 ...

  7. 网络安装CentOS 5.3

    转自网络安装CentOS 5.3 0. 基本要求 (1) 需要使用至少两台服务器:其中一台没有操作系统,是我们即将安装的服务器;另外一台是已经安装好操作系统的服务器,我们用来存储CentOS的安装文件 ...

  8. 第三章 传奇的开始--Delphi(附读书笔记)

    第三章 传奇的开始--Delphi "是惊世之作的Delphi让Borland重新站了起来,没有当初的Delphi,就没有今日的Borland!" "是Turbo Pas ...

  9. 主线程中有多个handler的情况

    工作中遇到了这么一种情况,有两个视图,都需要开启异步任务从服务器获取数据,每个view中创建一个Handler,注册到异步任务中去,当异步任务从服务器获取数据出错,或者出现io异常或者http协议异常 ...

  10. XP中IIS“HTTP 500 - 内部服务器错误”解决方法

    我先把主要过程叙述一下,叙述完有每个问题的具体操作方法. 今天我在XP上安装IIS,运行网站出现"HTTP 500 - 内部服务器错误". 打开HTML没有问题,打开ASP文件时就 ...