自定义String类,并且实现在STL容器中添加自定义的类型

13.44 编写标准库string类的简化版本,命名String。你的类应该至少有一个默认构造函数和一个接受C风格字符串指针参数的构造函数。使用allocator为你的String类分配所需内存。

13.47 添加拷贝构造函数和拷贝赋值运算符,并添加打印语句,则每次函数执行时打印一条信息。

13.48 定义一个vector<String>并在其上多次调用push_back。运行程序,观察String被拷贝了多少次。

#include<iostream>
#include<string>
#include<memory>
#include<utility>
#include<cstring>
#include<vector>
using namespace std;

class String
{
public:
    String()=default;
    String(char *c);
    String(const String&);
    String& operator=(const String&);
    string* begin() const { return elements;}
    string* end() const { return first_free;}
private:
    static allocator<string> alloc;
    string *elements;
    string *first_free;
};

allocator<string> String::alloc;
String::String(char *c)
{
    size_t capacity=strlen(c);
    auto data=alloc.allocate(capacity);
    auto dest=data;
    string s;
    s.copy(c,strlen(c));
    alloc.construct(dest++,s);
    elements=data;
    first_free=dest;
}

String::String(const String &s)
{
    cout<<"copy construct"<<endl;
    auto capacity=s.end()-s.begin();
    auto data=alloc.allocate(capacity);
    uninitialized_copy(s.begin(),s.end(),data);
    elements=data;
    first_free=data+capacity;
}

String& String::operator=(const String &s)
{
    cout<<"copy = construct"<<endl;
    auto capacity=s.end()-s.begin();
    auto data=alloc.allocate(capacity);
    uninitialized_copy(s.begin(),s.end(),data);
    if(elements)
    {
        auto begin=elements;
        auto end=first_free;
        while(begin!=end)
            alloc.destroy(begin++);
        alloc.deallocate(elements,first_free-elements);
    }
    elements=data;
    first_free=data+capacity;
    return *this;
}
int main()
{
    vector<String> vec;
    char ch[]="hello";
    char ch1[]="world!";
    cout<<vec.capacity()<<endl;
     cout<<endl;
    vec.push_back(String(ch));
    cout<<vec.capacity()<<endl;
    cout<<endl;
    vec.push_back(String(ch1));
    cout<<vec.capacity()<<endl;
    cout<<endl;
    vec.push_back(String(ch));
    cout<<vec.capacity()<<endl;
    cout<<endl;
    vec.push_back(String(ch1));
    cout<<vec.capacity()<<endl;
    cout<<endl;
    vec.push_back(String(ch1));
    cout<<vec.capacity()<<endl;
    cout<<endl;
    vec.push_back(String(ch1));
    cout<<vec.capacity()<<endl;
    return 0;
}

运行结果:

解释:http://blog.csdn.net/HEYUTAO007/article/details/6702626

时间: 2024-10-06 00:23:04

自定义String类,并且实现在STL容器中添加自定义的类型的相关文章

如何选择STL容器中对象的删除方法

备注:唯一从容器中除去一个元素的方法是在那个容器上调用一个成员函数. 以下介绍删除不同类型的容器中满足某种条件的值的方法,某种条件指的是 bool badValue(int value)返回true的情况. 1.序列容器 for(SeqContainer<int>::iterator i = c.begin(); i != c.end(); /*nothing*/) { if(badValue(*i)) { //something to do i = c.erase(i); } else ++

SpringBoot中在普通类里面加载Spring容器中的类

前言 在我们的工作中,经常会遇到需要在普通类中使用放在Spring容器中的类的情况.最常见的情况大概就是有一个类他的属性的是通过spring的配置文件读取的.这样这个类必然要交给Spring容器进行管理.这个时候如果我们在普通类中直接new这个类是不可以拿到的.属性值不会加载成功.下面介绍一个方法. 实现 封装一个beanutil 我们获取spring容器中的类,都从这个工具类里面来获取. import org.springframework.context.ConfigurableApplic

通过 Docker 实现在 Linux 容器中运行 Microsoft SQL Server 数据库

首先,我们需要输入以下命令来下载镜像(解压完成后大约1.35GB). docker pull microsoft/mssql-server-linux:2017-latest 运行“docker images”来进行确认. 运行容器 接下来,您需要运行它.为此,您需要接受许可协议,并为管理员帐户指定一个安全的密码.如果您想要开发者版本以外的东西,那么您也可以指定PID.还有很多其他的环境变量供您进行设置,您可以参考https://docs.microsoft.com/en-us/sql/linu

C++之运算符重载自定义String类

我这里使用的是vs2013 希望可以帮助到大家 第一个文件 MyString.h #pragma once #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; class MyString{ friend ostream&operator<<(ostream& cout, MyString &str); friend istream&operator>&

c++中STL容器中的排序

1.c++STL中只有list自带了排序函数: (1).若list中存放的是int类型或者string类型,直接利用sort即可: list <int> list1; list1.sort(); 此时默认为升序,若要使用降序,直接自定义cmp函数即可. (2).若存放的是结构体或其他指针类型,需要自己定义比较结构体: struct student { int num;}; struct node { bool operator()(student a,student b) return a.n

stl容器中的 .front()函数隐士转换

周末,睡了两个好觉.前天把周任务完成了,在看公司项目源码.发现std::map 的.front函数会发生隐士转换. 伪代码如下: std::map<int,int> m_map; int &i = m_map.front(): // .fornt 函数书上写的是返回一个引用. m_map.pop_push(); //弹出第一个 映射 return i; //当时就郁闷了,这样做不会出错吗? //仔细看是这样的 int i = m_map.front(); //这里转换了,当时蒙蒙冲的,

STL容器中的erase函数调用问题

自我感觉,erase函数返回一个迭代器,指向被删除元素的下一个位置,不是很合理. 啥也不说,直接上代码: int findNum = 2;    int array[] = { 1, 2, 2, 4, 5, 6 };    vector<int> ivec(array, array + sizeof(array) / sizeof(*array));    for (vector<int>::iterator iter = ivec.begin(); i != ivec.end()

自定义实现String类

自定义实现String类的内容 直接在代码中阐述:附有测试样例 代码: #include <iostream> //#include <cstring> using namespace std; class String { public: //ctor String(); String(const char* s); String(const char* s, size_t len); String(const String& rhs); String(size_t Le

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

第16章 string类和标准模板库 1. string容易被忽略的构造函数: string(size_type n, char c)长度为n,每个字母都为c string(const string & str, size_type pos = 0, size_type n = pos)初始化为str中从pos开始到结尾的字符,或从pos开始的n个字符 string(const char *s, size_type n)初始化为s指向的前n个字符,即使超过了s的结尾: string(Iter b