自定義簡易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());
		//註釋部分爲拷貝1實現
		/*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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章