自定义简易string类c++primer13.44

头文件

#pragma warning(disable:4996) //可参考上一篇解决c4996问题的博客
#include<iostream>
#include<memory>
#include<algorithm>
#include<utility>


class String {
public:
	String() { 
		elements = nullptr;
		first_free = nullptr;
	}
	String(char *c) {  //接受c风格的字符串,c指向字符串第一个字符
		auto c1 = const_cast<char *>(c);
		while (*c1) {
			++c1;
		}
		auto p = alloc_n_copy(c, c1);
		elements = p.first;
		first_free = p.second;
	}
	String(const String& s) {
		auto p = alloc_n_copy(s.elements, s.first_free);
		elements = p.first;
		first_free = p.second;
	}
	String &operator=(const String& s) {
		auto p = alloc_n_copy(s.elements, s.first_free);
		free();
		elements = p.first;
		first_free = p.second;
	}
	~String() {
		free();
	}
	void show() {
		auto p = elements;
		while (p != first_free) {
			std::cout << *p;
			++p;
		}
		std::cout << std::endl;
	}
	size_t size() { return first_free - elements; }
	String &operator+(String& s) {
		auto p = alloc.allocate(this->size() + s.size());
		//注释部分为拷贝实现
		/*auto dataMid = std::uninitialized_copy(this->elements, this->first_free, p);
		auto dataEnd = std::uninitialized_copy(s.elements, s.first_free, dataMid);
		this->free();
		this->elements = p;
		this->first_free = dataEnd;*/
		//下面采用了移动构造函数std::move,节省了拷贝开销
		auto dest = p; //指向新数组中下一个空闲位置
		auto elem = this->elements;  //指向就数组中下一个元素
		for (size_t i = 0; i != this->size(); ++i) {
			alloc.construct(dest++, std::move(*elem++));
		}
		elem = s.elements;
		for (size_t i = 0; i != s.size(); ++i) {
			alloc.construct(dest++, std::move(*elem++));
		}
		free();
		this->elements = p;
		this->first_free = dest;
		return *this;
	}
private:
	char *elements;  //指向字符串首字符
	char *first_free;  //指向字符串最后一个字符的后一个位置
    static std::allocator<char> alloc;  //类内静态成员要在类外进行定义初始化否则会出现LNK2001error
	static std::allocator<char> initalloc() {
		std::allocator<char> allo;
		allo.allocate(1);
		return allo;
	}
	std::pair<char*, char*> alloc_n_copy(const char*, const char*);
	void free();
};

std::allocator<char> String::alloc = initalloc();

std::pair<char*, char*> String::alloc_n_copy(const char* c1, const char* c2) {
	auto dataBeg = alloc.allocate(c2 - c1);
	auto dataEnd = std::uninitialized_copy(c1, c2, dataBeg);
	return std::make_pair(dataBeg, dataEnd);
}

void String::free() {
	if (elements) {
		std::for_each(elements, first_free, [this](char &rhs) {alloc.destroy(&rhs); });
		alloc.deallocate(elements, first_free - elements);
	}
}

主函数

#include<iostream>
#include"classString.h"

using namespace std;

int main() {
	String s("dasdsad11111");
	s.show();
	String s1(s);
	s1.show();
	String s2 = s;
	s2.show();
	cout << s2.size() << endl;
	s1 + s2;
	s1.show();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值