使用alloctor类来实现string类

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

#include <iostream>
#include <string>
#include <memory>
using namespace std;
const int incerment=10;
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 = 0; s[i]; i++)
            push_back(s[i]);
    }
    String(const String &s) :elements(nullptr), last_element(nullptr), space_end(nullptr){
        elements = alloc.allocate(s.size() * 2);
        last_element = uninitialized_copy(s.begin(), s.end(), elements);
        space_end = elements + s.size() * 2;
        uninitialized_fill(last_element, space_end, 0);
    }
    String(const size_t &len) :elements(nullptr), last_element(nullptr), space_end(nullptr){
        elements = alloc.allocate(len);
        uninitialized_fill_n(elements, len, 0);
        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*2);
        uninitialized_fill_n(elements, n, ch);
        last_element = elements + n;
        space_end = elements + n * 2;
    }
    ~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, 0);
        }
        *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 = 0;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,0);
        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()+3,b.end()), e(12,‘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[0] <<"    "<< h[h.size() - 1];
    }
    _CrtDumpMemoryLeaks();
}

时间: 2024-12-21 14:42:27

使用alloctor类来实现string类的相关文章

第十天 Object类(部分)和String类

Java的API Java的API(API:Application(应用)Programming(程序)Interface(接口)) JavaAP就是JD中提供给我们使用的类,这些类将底层代码实现封装起来了.我们不需要关系这些类是如何实现的,只需要虚心如何使用这些类. JKD安装目录下有个src.zip文件,这个文件解压后里面的内容就是所有java的类.可以参看对应的源码. 其次我们可以通过查找帮助文档的方式,来了解Java提供的API如何使用哪些类 Object类的概述 构造方法public

设计String类,并且在String类中使用运算符重载

passport.baidu.com/?business&un=%E6%B5%8E%E5%8D%97%E5%93%AA%E6%9C%89%E5%A4%9C%E6%83%85%E4%B8%80#0 passport.baidu.com/?business&un=%E6%B5%8E%E5%8D%97%5F%E7%BE%8E%E5%A5%B3%E6%8C%89%E6%91%A9#0 passport.baidu.com/?business&un=%E5%8D%97%E9%98%B3%5F

mat 类 ,datetime 类 占位符 string类

C#中是否可以继承String类

C#中是否可以继承String类? 答:String类是sealed类故不可以继承. 当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承. 在下面的示例中,类 HoverTree 从类 Keleyi 继承,但是任何类都不能从类 HoverTree 继承. class Keleyi {} sealed class HoverTree : Keleyi {} 还可以在重写基类中的虚方法或虚属性的方法或属性上使用 sealed 修饰符. 这将使您能够允许类从您的类继承,并防止它们重

学java教程之String类

学编程吧学java教程之String类发布了,欢迎通过xuebiancheng8.com来访问 java类中的String类应该是用的最多的一个类,我们时时刻刻都离不开String类,时时刻刻都在用,面试的时候经常考,比方说问String类是不是基本数据类型.答案是否定了,String类不是基本数据类型,只不过String类和基本数据类型的用法很相似. 下面来看String类的用法. String str= “abc”;//定义了一个字符串abc String str1= new String(

.Net的String类与StringBuilder类操作

关于.NET提供了许多可以直接使用的类代码,常用的包括Convert类.String类和StringBuilder类.DateTimel类和TimeSpan类.Math类等等. 其中Convert类提供的方法都是静态方法,主要用于数据类型的转换: 例如: 字符串数据类型  -----> 整形 string str ="123"; int Getstr = Convert.Int32(str); 但要注意类型转换的取值范围. 当然DateTime类和TimeSpan类是针对时间这一

【Java 进阶篇】【第一课】String类

引用 String类包含在java.lang包中.这个包会在Java启动的时候自动import,所以可以当做一个内置类(built-in class).我们不需要显式的使用import引入String类. 创建 String类是唯一一个不需要new关键字来创建对象的类.使用的时候需要注意 String s = "Hello World!"; System.out.println(s); 操作 可以用+实现字符串的连接(concatenate),比如: "abc" +

【java】String类和StringBuffer类常用操作

String类是字符串常量,是不可更改的常量.而StringBuffer是字符串变量,它的对象是可以扩充和修改的.StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类.所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入.删除等操作,使用StringBuffer要更加适合一些. String类主要方法的使用一.创建并初始化字符串: String s = "hello!"; //使用字符串常量直接初始化 String(); //使用构造方法

全面深入介绍C++字符串:string类

http://blog.csdn.net/liuliming3000/article/details/1809385 1 从C到C++ string类 2 string类的构造函数 3 string类的字符操作 4 string的特性描述 5 string类的输入输出操作 6 string的赋值 7 string的连接 8 string的比较 9 string类的查找函数 10 string类的替换函数 11 string类的插入函数 12 string类的删除函数 13 string类的迭代器