根据C++ Primer 5th编写的自定义String类

String.h

#ifndef STRING_H
#define STRING_H

#include <iostream>
#include <memory>
#include <cstring>

class String
{
	friend String operator+(const String&, const String&);
	friend std::ostream &operator<<(std::ostream&, const String&);
	friend bool operator==(const String&, const String&);
	friend bool operator!=(const String&, const String&);
	friend bool operator<(const String&, const String&);
public:
	String() : sz(0), p(nullptr) {}
	String(const String &);
	String(const char *);
	String(size_t, char);
	~String() throw();
	String& operator=(const String &);
	String& operator=(const char *);
	String& operator=(char);
	String& operator+=(const String &);
	String& operator+=(const char *);
	char operator[](size_t n)              { return *(p + n); }
	const char operator[](size_t n) const  { return *(p + n); }

	String(String &&) throw();
	String& operator=(String &&) throw();

	const char* begin()	        { return p; }
	const char* begin() const   { return p; }
	const char* end()           { return p + sz; }
	const char* end() const     { return p + sz; }
	size_t size() const         { return sz; }

private:
	size_t sz;
	char *p;
	static std::allocator<char> alloc;
};

inline
String::String(const String &s) : sz(s.sz), p(alloc.allocate(sz))
{
	// 将s中的内容拷贝到分配好的内存中
	std::uninitialized_copy(s.begin(), s.end(), p);
	//std::cout << "调用拷贝构造函数" << std::endl;
}

inline
String::String(const char *s)
{
	size_t len = strlen(s);
	p = alloc.allocate(len);
	sz = len;
	std::uninitialized_copy(s, s + len, p);
}

inline
String::String(size_t n, char c)
{
	p = alloc.allocate(n);
	sz = n;
	std::uninitialized_fill_n(p, sz, c);
}

inline
String::~String() throw()
{
	if(p)
		alloc.deallocate(p, sz);
}

inline
String& String::operator=(const String &s)
{
	// 分配sz大小的内存
	auto newdata = alloc.allocate(s.sz);
	// 将s中的内容拷贝到分配好的内存中,首地址为newdata
	std::uninitialized_copy(s.begin(), s.end(), newdata);
	// 释放原分配的内存
	if(p)
		alloc.deallocate(p, sz);
	// 更新sz和p
	sz = s.sz;
	p = newdata;
	//std::cout << "调用拷贝赋值运算符" << std::endl;
	return *this;
}

inline
String& String::operator=(const char *s)
{
	if(p)
		alloc.deallocate(p, sz);
	size_t len = strlen(s);
	p = alloc.allocate(len);
	std::uninitialized_copy(s, s + len, p);
	sz = len;
	return *this;
}

inline
String& String::operator=(char c)
{
	if(p)
		alloc.deallocate(p, sz);
	p = alloc.allocate(1);
	*p = c;
	sz = 1;
	return *this;
}

inline
String::String(String &&s) throw() : sz(s.sz), p(s.p)
{
	s.sz = 0;
	s.p = nullptr;
}

inline
String& String::operator=(String &&s) throw()
{
	if(this != &s)
	{
		if(p)	alloc.deallocate(p, sz);
		sz = s.sz;
		p = s.p;
		s.sz = 0;
		s.p = nullptr;
	}
	return *this;
}

#endif


String.cpp

#include "String.h"

// 这一句很关键,因为这样程序才会知道是调用String类中的alloc;否则程序运行时可能找不到alloc
std::allocator<char> String::alloc;

std::ostream &operator<<(std::ostream &os, const String &s)
{
	for(auto cp = s.begin(); cp != s.end(); ++cp)
		os << *cp;
	return os;
}

String operator+(const String &s1, const String &s2)
{
	String s;
	s.sz = s1.size() + s2.size();
	// 分配s1.size()+s2.size()的内存
	s.p = String::alloc.allocate(s.sz);
	// 将s1和s2的内容拷贝到分配好的内存中
	std::uninitialized_copy(s1.begin(), s1.end(), s.p);
	std::uninitialized_copy(s2.begin(), s2.end(), s.p + s1.size());
	return s;
}

String& String::operator+=(const String &rhs)
{
	auto newdata = alloc.allocate(sz + rhs.sz);
	std::uninitialized_copy(p, p + sz, newdata);
	std::uninitialized_copy(rhs.begin(), rhs.end(), newdata + sz);
	if(p)	alloc.deallocate(p, sz);
	sz += rhs.sz;
	p = newdata;
	return *this;
}

String& String::operator+=(const char *rhs)
{
	size_t rhs_len = strlen(rhs);
	auto newdata = alloc.allocate(sz + rhs_len);
	std::uninitialized_copy(p, p + sz, newdata);
	std::uninitialized_copy(rhs, rhs + rhs_len, newdata + sz);
	if(p)	alloc.deallocate(p, sz);
	sz += rhs_len;
	p = newdata;
	return *this;
}

bool operator==(const String &s1, const String &s2)
{
	if(s1.sz != s2.sz)	return false;
	size_t sz = s1.sz;
	for(size_t i = 0; i < sz; ++i)
	{
		if(*(s1.p + i) != *(s2.p + i))
			return false;
	}
	return true;
}

bool operator!=(const String &s1, const String &s2)
{
	return !(s1 == s2);
}

bool operator<(const String &s1, const String &s2)
{
	// 1. 长度不相同,但较短字符串与较长字符串对应的位置相同,则较短字符串<较长字符串
	// "Hello" < "Hello World"
	// 2. 某些字符对应不一致,则比较第一对相异位置
	// "Hello" < "Hiya"
	size_t short_size = s1.size();
	if(s2.size() < s1.size())
		short_size = s2.size();
	
	for(size_t i = 0; i < short_size; ++i)
	{
		if(*(s1.p + i) < *(s2.p + i))
			return true;
		else if(*(s1.p + i) > *(s2.p + i))
			return false;
	}
	if(s1.size() < s2.size())
		return true;
	else
		return false;
}

Test.cpp

#include <iostream>
using std::cout; using std::endl;

#include "String.h"

int main()
{
	String s1 = "Hello", s2;
	s2 = "Hiya";
	cout << s1 << endl;
	cout << s2 << endl;

	if(s1 < s2)
		cout << "s1 < s2" << endl;
	else if(s1 == s2)
		cout << "s1 == s2" << endl;
	else
		cout << "s1 > s2" << endl;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值