重载技巧+简单实现string和Vector

一、重载

1. 赋值(=),下标([]),调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些操作符定义为非成员函数将在编译时标记为错误。
2. 像赋值一样,复合赋值操作符通常应定义为类的成员。与赋值不同的是,不一定非得这样做,如果定义为非成员复合赋值操作符,不会出现编译错误。
3. 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增,自减和解引用,通常应定义为类成员。
4. 对称的操作符,如算术操作符,相等操作符,关系操作符和位操作符,最好定义为普通非成员函数。
5.io操作符必须定义为非成员函数,重载为类的友元


二、String类

#include<iostream>
#include<string.h>
using namespace std;


class String{

public:

	// type
	typedef char*	iterator;
	typedef size_t	size_type;

	//constructor
	String(const char *str=NULL);//输入参数为const型

	//copy like
	String(const String &other);

	String& operator=(const String &other);//返回值是个引用 &

	~String(void);

	//functions
	size_t size(){
		return strLength;
	}

	iterator begin(){	return pStr;	}

	iterator end()	{	return pStr+strLength;	}

	String subStr(String::iterator pStart,size_type len);
	
	
	//operator
	bool operator==(const String& other);
	String& operator+=(const String&); 

	friend ostream& operator<<(ostream& os, const String& str);

	
private:
	size_t strLength;
	char *pStr;
};

String::String(const char *str){

	cout<< "c-tor"<<endl;

	if(str==NULL){// 对空字符串自动申请存放结束标志'\0'的
		pStr=new char[1];//对m_data加NULL 判断 
		*pStr='\0';
		strLength=0;
	}else{
		int len=strlen(str);
		pStr=new char[len+1];
		strcpy(pStr,str);
		strLength=len;
	}
}

String::String(const String &other){
	
	cout<< "copy c-tor"<<endl;

	int len=strlen(other.pStr);
	pStr=new char[len+1];
	strcpy(pStr,other.pStr);
	strLength=len;
}

String& String::operator=(const String& other){

	cout<< "assign ="<<endl;

	if(this==&other)//证同测试
		return *this;
	delete[] pStr;//记得释放内存
	pStr=NULL;

	int len=strlen(other.pStr);
	pStr=new char[len+1];

	strcpy(pStr,other.pStr);
	strLength=len;

	return *this;
}

String::~String(){
	cout<< "d-tor"<<endl;
	delete pStr;
}

String String::subStr(iterator pStart,size_type len){
	
	size_t n=strlen(pStart)>len? len : strlen(pStart);
	
	char *p=new char[n+1];
	int i;
	for( i=0;i<n;++i){
		p[i]=pStart[i];
	}
	p[i]='\0';
	String ret(p);
	return ret;
}
String& String::operator+=(const String& str){

	if(this == &str){//防止s+=s;这种自加操作,需要证同测试
		String copy(str);
		return *this+=copy;
	}
	strLength += str.strLength;
	char* pOld = pStr;
	pStr = new char[strLength+1];
	strcpy(pStr,pOld);

	delete[] pOld;
	strcat(pStr,str.pStr);

	return *this;
}
bool String::operator==(const String& other){
	return strcmp(pStr,other.pStr)==0;
}

ostream& operator<<(ostream& os, const String& str){
	os << str.pStr;
	return os;
}



int main()  
{  
	String s = "goodmorningmrs!";  
	String s2 = s;  
	String ss = "nihaomrs!";  
	cout<< s << endl; 
	cout<< s2 <<endl; 
	cout<<boolalpha<<(ss == s)<<endl;  

	ss+=s2;
	cout<<ss<<endl;	

	String::iterator iter=s.begin();
	String sub=s.subStr(iter,s.size());
	cout<<sub<<endl;
	cout<<"sub.size()="<<sub.size()<<endl;
	String::size_type a=sub.size();
	cout<< "now a="<<a <<endl;



	return 0;
}  

三、Vector

//2014-08-13
#ifndef MYVECTOR_H
#define MYVECTOR_H

#include<memory.h>
#include<cstddef>
using namespace std;

template<typename T> class Vector{
public:
	Vector():elements(0),first_free(0),end(0){}
	
	void push_back(const T&);
	
	void reserve(const size_t capa);

	//调整vector大小,使其能容纳n个元素;
	//如果n小于Vector当前大小,则删除多余元素
	//否则,添加采用值初始化的新元素
	void resize(const size_t n);

	//调整Vector大小,使其能容纳n个元素,添加所有元素的值都为t
	void resize(const size_t n ,const T& t);

	//下标操作
	const T& operator[](const size_t) const;
	T& operator[](const size_t );
	
	//返回Vector大小
	size_t size(){
		return first_free - elements;
	}

	//返回容量
	size_t capacity(){
		return end-elements;
	}
	
private:
	static std::allocator<T> alloc;//用于获取未构造内存的对象
	void reallocate();//获得更多空间并复制现有元素
	T* elements;//指向第一个元素的指针
	T* first_free;//指向第一个自由元素的指针
	T* end;		//指向数组末端的下一个元素位置的指针
}
#endif
	
//cpp Vector实现

//
template<class T>
allocator<T> Vector<T>::alloc;

template<class T>
void Vector<T>::push_back(const T& t){
	if(first_free == end)//已用完所分配的空间
		reallocate();
	alloc.construct(first_free,t);
	++first_free;
}

template<class T>
void Vector<T>::reallocate(){//重分配
	ptrdiff_t size = first_free - elements;
	ptrdiff_t newcapacity= 2* max(size,1);

	//分配空间以保存newCapacity个T类型的元素
	T* newelements=alloc.allocate(newcapacity);

	//在新空间中构造现有元素的副本
	uninitialized_copy(elements,first_free,newelements);

	//逆序撤销旧元素
	for(T* p= first_free; p!=elements;){
		alloc.destroy(--p);
	}
	//释放旧元素占用的内存
	if (elements){
		alloc.deallocate(elements,end-elements);
	}

	//使数据结构指向新元素
	elements=newelements;
	first_free=elements+size;
	end=elements+newcapacity;
}


template<class T>
void Vector<T>::reserve(const size_t capa){//预留的容量

	//计算当前大小
	size_t size=first_free-elements;
	//分配可保存capa个T类型元素的空间
	T* newelements = alloc.allocate(capa);

	//在新分配的空间中构造现有元素的副本
	if (size<=capa){
		uninitialized_copy(elements,first_free,newelements);
	}else{
		uninitialized_copy(elements,elements+capa,newelements);
	}
	//逆序撤销内存中构造的对象
	for(T*p=first_free;p!=elements; ){
		alloc.destroy(--p);
	}
	//释放旧元素占用的内存
	if (elements){
		alloc.deallocate(elements,end-elements);
	}

	//使数据结构指向新元素
	elements=newelements;
	first_free=elements+min(size,capa);
	end=elements+capa;

}

template<class T>
void Vector<T>::resize(const size_t n){
	//计算当前大小及容量
	size_t size=first_free-elements;
	size_t capacity=end-elements;

	if(n>capacity){
		//获取更多空间并复制现有元素
		reallocate();
		uninitialized_copy(elements+size,elements+n,T());
	}else if(n>size){
		uninitialized_copy(elements+size,elements+n,T());
	}else{
		//逆序撤销内存中构造的对象
		for(T*p=first_free;p!=elements+n; ){
			alloc.destroy(--p);
		}
		

		//使数据结构指向新元素
		first_free=elements+n
		
}

template<class T>
void Vector<T>::resize(const size_t n,const T &t){
	//计算当前大小及容量
	size_t size=first_free-elements;
	size_t capacity=end-elements;

	if(n>capacity){
		//获取更多空间并复制现有元素
		reallocate();
		uninitialized_copy(elements+size,elements+n,t);
	}else if(n>size){
		uninitialized_copy(elements+size,elements+n,t);
	}else{
		//逆序撤销内存中构造的对象
		for(T*p=first_free;p!=elements+n; ){
			alloc.destroy(--p);
		}
		

		//使数据结构指向新元素
		first_free=elements+n
		
}

template<class T>
T& vector<T>::operator[](const size_t index){
	return elements[index];
}

template<class T>
const T& vector<T>::operator[](const size_t index) const{
	return elements[index];
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值