C++ primer 丐版String

#ifndef STRVEC_H_
#define STRVEC_H_

#include <iostream>
#include <stdio.h>
#include <string>
#include <memory>
#include <algorithm>
#include <initializer_list>
#include <memory>
#include <vector>
#include <stdexcept>
#include <fstream>
#include <sstream>
#include <set>
#include <map>

using std::cout;
using std::endl;

class String
{
public:
    String() :first_c(nullptr), last_c(nullptr) {};
    String(const char* chr);
    String(const String& s);
    String(String&& s) noexcept;//移动构造函数
    String& operator=(const String& s);
    String& operator=(String&& s) noexcept;
    char* begin() const { return first_c; }
    char* end() const { return last_c; }
    char* c_str() { return first_c; }
    ~String();
private:
    std::allocator<char> alloc;
    std::pair<char*, char*>alloc_n_copy(const String& s);
    void free();
    char* first_c;
    char* last_c;
};

String::String(const char* chr)
{
    auto len = strlen(chr) + 1;
    auto beg = alloc.allocate(len);
    first_c = beg;
    last_c = beg + len;
    memcpy(first_c, chr, len);
    printf("默认构造函数\n");
}

String::String(const String& s)
{
    auto p = alloc_n_copy(s);
    first_c = p.first;
    last_c = p.second;
    std::cout << "拷贝构造函数" << std::endl;
}

String::String(String&& s) noexcept :
    alloc(std::move(s.alloc)), first_c(std::move(s.first_c)), last_c(std::move(s.last_c))
{
    printf("%s 移动构造函数\n", first_c);
    s.first_c = nullptr;   s.last_c = nullptr;
}


String::~String()
{
    free();
}

std::pair<char*, char*> String::alloc_n_copy(const String& s)
{
    auto data = alloc.allocate(s.last_c - s.first_c);
    return { data, std::uninitialized_copy(s.first_c, s.last_c, data) };
}

String& String::operator=(const String& s)
{
    auto tmp = alloc_n_copy(s);
    free();
    first_c = tmp.first;
    last_c = tmp.second;
    printf("拷贝赋值运算符\n");
    return *this;
}

String& String::operator=(String&& s) noexcept
{
    if (this != &s)
    {
        free();
        alloc = std::move(s.alloc);
        first_c = std::move(s.first_c);
        last_c = std::move(s.last_c);
        s.first_c = nullptr; s.last_c = nullptr;
        printf("移动赋值运算符");
    }
    return *this;
}

void String::free()
{
    if (first_c)
    {
        std::for_each(first_c, last_c, [this](char& cp) { alloc.destroy(&cp); });
        alloc.deallocate(first_c, last_c - first_c);
    }
}

#endif
posted @   xiazichengxi  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
主题色彩