一、重载
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];
}