首先我们要理解清楚private属于私有变量只能被本类中的成员函数所引用。类似于Int& Int::operator +=(const Int&rhs)你会发现+=需要两个变量,属于双目运算符,但是形参列表里面只有一个参数,所以很显然他是成员函数。(成员函数的返回值就是本类的类型,形参个数在原来基础上减一)
但是普通函数,就是通俗讲的普通函数
譬如:
const Int operator +(const Int&lhs,const Int& rhs)
{
Int ret(lhs);
ret+=rhs;
return ret;
}
因为有些运算符属于单目运算符,它本身就无法利用成员函数重展
记住:双目运算符建议用非成员函数重载
流输出运算符建议非成员函数重载
当然c++规定= 【】 ()必须成员函数重载
将+= -= /= %= *= &= ^= >>= <<= 单目和算数运算符用成员函数重载
区别
:成员函数可以直接调用类中的私有变量
例如
Int& Int::operator +=(const Int&rhs)
{
value+=rhs.value;
return *this;
}
但是普通函数对于类中的private来说是无法调用的所以需要接口函数
例如
int getsize()const{return size;}
用成员函数你还可以直接用*this指针调用前面被隐藏的参数(即被剪掉的那个参数)
Int& Int::operator +=(const Int&rhs)
{
this->value+=rhs.value;///你可以写上this,也可以不写
return *this;///返回时直接返回他的值this只是地址 *this才是提取出来的值
}
接着要学会区分前缀++和后缀++
就是说直接按照你理解的 a=1 b=a++ 和b=++a
这是两个结果,第一个后缀的b=1,因为先赋值后加加
而前缀的b=2 不妨看下面的代码
Int& Int::operator ++()///前缀
{
++value;///直接加即可
return *this;
}
Int Int::operator ++(int tmp)///后缀 这里的tmp作为参数无实际效果,只是当作区分 前缀和后缀的参考
{
Int ret(*this);///按照上面的理解a还是加了1,但是赋值给b的还是本值
++value;///所以先拷贝一份,然后再将a+1,但是返回的是之前的拷贝值
return ret;
}
不同位置的const用途
形参列表中的const 只是为了防止进行拷贝时将形参改变,影响逻辑含义
最后的const则是说明该函数不允许改变类的成员
接下来的 get函数 disp函数均要用到
const Int operator +(const Int&lhs,const Int& rhs)
{
Int ret(lhs);
ret+=rhs;
return ret;
}
int Int::getvalue()const{return value;}
总结
:+ - * / % 函数均使用const+类名 且不要声明作用域 只有成员函数才需要声明
而= += *= /= 则是类名加上& 作用域 函数名
<< >>则用普通函数
关于作用域 只有构造函数 才是类名::函数类型
其他成员函数都是函数类型 类名::函数名
int& Array::operator [](int pos)///普通版本
{
return data[pos];
}
const int& Array::operator [](int pos)const ///之前const用法所讲的
{
return data[pos];
}
总的类
class Int{
private:
int value;
public:
};
Int::Int():value(0){}///只有构造函数才需要列表初始化,其他函数会报错
Int::Int(int v):value(v){}///拷贝构造
Int::Int(const Int& rhs):value(rhs.value){}///拷贝构造
Int::~Int(){}///析构
int Int::getvalue()const{return value;}
void Int::setvalue(int v){value=v;}
Int& Int::operator =(const Int&rhs)
{
if (this!=&rhs)
{
this->value=rhs.value;
}
return *this;
}
Int& Int::operator +=(const Int&rhs)
{
value+=rhs.value;
return *this;
}
Int& Int::operator ++()
{
++value;
return *this;
}
Int Int::operator ++(int tmp)
{
Int ret(*this);
++value;
return ret;
}
const Int operator +(const Int&lhs,const Int& rhs)
{
Int ret(lhs);///先调用拷贝构造初始化
ret+=rhs;
return ret;
}
bool operator ==(const Int&lhs,const Int& rhs)
{
return lhs.getvalue()==rhs.getvalue();
}
std::ostream& operator <<(std::ostream&os,const Int &rhs)
{
return os<<rhs.getvalue();///把os理解为cout即可
}
std::istream& operator >>(std::istream&is,const Int& rhs)
{
int sum;
is>>sum;///将is理解为cin
rhs.setvalue(sum);
return is;
}
class Array{
private:
enum{SIZE=1000};
int data[SIZE];
int size;
public:
int getsize()const{return size;}
};
Array::Array():size(0){}
Array::Array(const Array& rhs):size(rhs.size)
{
for (int i=0;i<rhs.size;++i)
{
data[i]=rhs.data[i];
}
}
Array::Array(const int a[],int n):size(n)
{
forr (int i=0;i<n;++i)
{
data[i]=a[i];
}
}
Array::Array(int count,int n):size(n)
{
forr (int i=0;i<n;++i)
{
data[i]=count;
}
}
void Array::insert(int pos,int value)
{
for(int i=size-1;i>pos;--i)///注意要从后往前,否则前面的会把后面的全部覆盖
{
data[i+1]=data[i]
}
data[pos]=value;
++size;
}
int Array::at(int pos)const
{
return data[pos];
}
void Array::remove(int pos)
{
for (int i=pos;i<size-1;++i)///从前往后,慢慢往前移
{
data[i]=data[i+1];
}
--size;
}
void Array::modify(int pos,int newvalue)
{
data[pos]=newvalue;
}
void Array::disp()const///凡是直接输出值后面均要加const
{
for (int i=0;i<size;++i)
{
cout<<at(i)<<' ';
}
cout<<endl;
}
Array& Array::operator =(const Array&rhs)
{
if (this!=&rhs)
{
size=rhs.size;
for (int i=0;i<size;++i)
{
data[i]=rhs.data[i];
}
}
return *this;
}
int& Array::operator [](int pos)
{
return data[pos];
}
const int& Array::operator [](int pos)const
{
return data[pos];
}
bool operator <(const Array&lhs,const Array&rhs)
{
int n=lhs.getsize();
if (n>rhs.getsize())
n=rhs.getsize();
for(int i=0;i<n;++i)
{
if (lhs[i]<rhs[i])return true;
else if (lhs[i]>rhs[o])return false;
}
return lhs.getsize()<rhs.getsize();
}
bool operator ==(const Array&lhs,const Array&rhs)
{
if (lhs.getsize()!=rhs.getsize())
return false;
for(int i=0;i<lhs.getsize();++i)
{
if (lhs[i]!=rhs[i])
return false;
}
return true;
}
const Array operator +(const Array&lhs,const Array&rhs)///两个形参的普通函数 故不要加上作用域
{
Array ret(lhs);
for (int i=0;i<rhs.getsize();++i)
{
ret.insert(lhs.getsize(),rhs.at(i));
}
return ret;
}
std::ostream& operator <<(ostream&os,const Array&rhs)
{
for(int i=0;i<rhs.getsize();++i)
{
os<<rhs.at(i)<<' ';
}
return os;
}
class ArrayList{///大部分和Array类很像,一个用数组,一个new
private:
int *data;
int capacity;
int size;
public:
};
ArrayList::ArrayList():data(0),size(0),capacity(1)
{
data=new int[capacity];///new
}
ArrayList::ArrayList(const ArrayList&rhs):data(0),size(rhs.size),capacity(rhs.capacity)
{
data=new int[capacity];
for (int i=0;i<size;++i)
{
data[i]=rhs.data[i];
}
}
ArrayList::ArrayList(const int a[],int n):data(0),size(n),capacity(n)
{
data=new int[capacity];
for (int i=0;i<n;++i)
{
data[i]=a[i];
}
}
ArrayList::ArrayList(int value,int n):data(0),size(n),capacity(n)
{
data=new int[capacity];
for (int i=0;i<n;++i)
{
data[i]=value;
}
}
ArrayList::~ArrayList()
{
delete []data;///一定要记得析构
}
void ArrayList::setcapacity(int newcapacity)///设置容量
{
int *pt=data;///将原来的pt指向data的地址,然后让data进行重新new值
data= new int[capacity=newcapacity];
for (int i=0;i<size;++i)
{
data[i]=pt[i];///最后把pt指向的原来的data的值返回给新的扩容的data
}
delete []pt;///最后要删除原来的pt也就是原来的data的容量
}
void ArrayList::insert(int pos,int value)
{
if (capacity==size)
{
setcapacity(capacity+capacity);///一般扩容两倍
}
for (int i=size;i>pos;--i)
{
data[i+1]=data[i];
}
++size;
}
int ArrayList::at(int pos)
{
return data[i];
}
void ArrayList::modify(int pos,int newvalue)
{
data[i]=newvalue;
}
void ArrayList::remove(int pos)
{
for (int i=pos;i<size-1;++i)
{
data[i]=data[i+1];
}
--size;
}
ArrayList& ArrayList::operator =(const ArrayList&rhs)
{
if (this!=&rhs)
{
if (capacity<rhs.size)
{
setcapacity(rhs.size);
}
for (int i=0;i<rhs.size;++i)
{
data[i]=rhs.data[i];
}
}
size=rhs.size;
return *this;
}
bool operator == (const ArrayList&lhs,const ArrayList&rhs)
{
if (lhs.getSize()!=rhs.getSize())
return false;
int n=lhs.getSize();
for (int i=0;i<n;++i)
{
if (lhs.at(i)!=rhs.at(i))
return false;
}
return true;
}
ArrayList& ArrayList::operator +=(const ArrayList&rhs)
{
if (capacity<rhs.size+size)
{
setcapacity(size+rhs.size);
}
for(int i=0;i<rhs.size;++i)
{
data[i+size]=rhs.data[i];
}
size=size+rhs.size;
return *this;
}
ArrayList& ArrayList::operator [](int pos)
{
return data[pos];
}
const ArrayList& ArrayList::operator [](int pos)const
{
return data[pos];
}
std::ostream& operator << (std::ostream&os,const ArrayList&rhs)
{
for (int i=0;i<rhs.getSize();++i)
{
os<<rhs[i]<<' ';
}
return os;
}
class LinkedList{///链表的话一开始比较难以理解,你可以把它想象成一些小方格,它们是直线的,
///每个相邻的之间有一条线也就是next,首先的话就需要一个空的表头也就是*head,他没有任何逻辑意义,只是说为了能让删除操作和理论一致,保证最后一个元素也能被删除
public:
struct Node{
int data;
Node *next;
Node (int a,Node *b):data(a),next(b){}
};
public:
Node *head;
int size;
};
LinkedList::LinkedList():head(0),size(0)
{
head=new Node(0,0);///初始化
}
LinkedList::LinkedList(const LinkedList&rhs):head(0),size(rhs.size)
{
head=new Node(0,0);
Node *q=head;///先建立表头
for(Node *p=rhs.head->next///第一个元素;p,p=p->next)///你把他理解为
///for(int i=;i<n;++i)就可以了
{
q->next=new Node(p->data,0);
}
}
LinkedList::LinkedList(const int a[],,int n):head(0),size(n)
{
head=new Node(0,0);
Node *q=head;
for(int i=0;i<n;++i)
{
q->next=new Node(a[i],0);
q=q->next;
}
}
LinkedList::LinkedList(int value,,int n):head(0),size(n)
{
head=new Node(0,0);
Node *q=head;
for(int i=0;i<n;++i)
{
q->next=new Node(value,0);
q=q->next;
}
}
LinkedList::~LinkedList()
{
Node *p,*q;
q=head;
p=head->next;
delete q;///先析构表头之后慢慢往后移
while(p)
{
q=p;
p=p->next;
delete q;
}
}
LinkedList:: Node* LinkedList::advance(int pos)const
{
Node *p=head;///由于最先的一个是空的表头,所以要从-1开始
for (int i=-1;i<pos;++i)
{
p=p->next;
}
return p;
}
int LinkedList::at(int pos)const
{
Node *p=advance(pos);
return p->data;
}
void LinkedList::remove(int pos)///自己画个图,三个格子删除中间那个
///前面的格子的next直接指向第三个格子就行
{
Node *p=advance(pos-1);
Node *q=p->next;
p->next=q->next;
--size;
}
void LinkedList::insert(int pos,int value)
{
Node *p=advance(pos-1);
Node *q=new Node(value,p->next);///插入稍微麻烦点,先建立一个格子,这个格子指向原来的两个格子之间,
///先将原来第一个格子指向后面格子的next,转为新格子指向后一个格子,再将前面的格子next指向新格子 画图你就理解了
p->next=q;
++size;
}
void LinkedList::modify(int pos,int newvalue)
{
Node *p=advance(pos);
p->data=newvalue;
}
void LinkedList::disp()const
{
for (LinkedList::Node *p=this->head->next;p;p=p->next)///这里要特别注意,因为disp是普通函数,现在他调用的是NOde是属于类里面的所以需要声明作用域
{
cout<<p->data<<' ';
}
cout<<endl;
}
LinkedList& LinkedList::operator =(const LinkedList&rhs)
{
if (&rhs!=this)
{
while (0!=size)remove(0);
Node *q=head;
for (Node *p=rhs.head->next;p;p=p->next)
{
q->next = new Node(p->data,0);
q = q->next;
}
size = rhs.size;
}
return *this;
}
LinkedList& LinkedList::operator +=(const LinkedList&rhs)
{
Node *p = advance(size-1);
for (Node *rp=rhs.head->next;rp;rp=rp->next)
{
Node *q = new Node(rp->data,0);
p->next = q;
p = q;
}
size+=rhs.size;
return *this;
}
int& LinkedList::operator [] (int pos)
{
Node*p = advance(pos);
return p->data;
}
const int& LinkedList::operator [] (int pos)const
{
Node*p = advance(pos);
return p->data;
}
int LinkedList::compareTo(const LinkedList&rhs)const
{
int n=size;
int m=rhs.size;
n=min(m,n);
for(int i=0;i<n;++i){
if(advance(i)->data<rhs.advance(i)->data)return -1;
if(advance(i)->data>rhs.advance(i)->data)return 1;
}
if (size<rhs.size)
return -1;
else if (size==rhs.size)
return 0;
else
return 1;
}
void LinkedList::disp(ostream&os)const
{
for(int i=0;i<size;++i){
os<<advance(i)->data<<" ";
}
}
你会发现只有个别的例如析构函数有所区别其他的不尽相同,所以自行理解。时间来不及画图,望谅解。