下面这段的程序,类声明中的运算符重载声明和定义都是正确的,前置自加。
class lianbiao
{
public:
int a;
lianbiao * next;
lianbiao* operator ++();
};
lianbiao* lianbiao::operator++()
{
cout<<"+ +"<<endl;
return this->next;
}
下面的代码,
class lianbiao
{
public:
int a;
lianbiao * next;
//lianbiao * operator + (lianbiao *p,int b);//这种声明是错的,双目运算符只需指明一个操作数,这样是该运算符有三个操作数,
lianbiao * operator + (int b);//重载+,产生后续节点,并返回该新节点的地址
lianbiao * operator ++();//前置自加,产生新的后续节点,并为新节点的成员a 赋值为a+1,返回新节点的地址
lianbiao * operator ++(int);//后置自加,产生新的后续节点,并为新节点的成员a 赋值为a+1,返回源节点地址
};
/*
lianbiao* lianbiao::operator + (lianbiao *p,int b)
{
p->next=new lianbiao;
(p->next)->a=b;
(p->next)->next=NULL;
return p->next;
}*/
lianbiao * lianbiao::operator+(int b)
{
this->next=new lianbiao;
this->next->a=b;
this->next->next=NULL;
return this->next;
}
lianbiao * lianbiao::operator++()
{
this->next=new lianbiao;
this->next->a=this->a+1;
this->next->next=NULL;
return this->next;
}
lianbiao * lianbiao::operator++(int)
{
this->next=new lianbiao;
this->next->a=this->a+1;
this->next->next=NULL;
return this;
}
void main()
{
lianbiao aa;
aa.a=8;
aa.next=NULL;
lianbiao *p=(aa+6);//声明指针并赋值为aa->next;
cout<<p->a<<endl;//查看结果
delete p;
p=++aa;//aa自加产生新节点并将地址赋值给p
cout<<p->a<<endl;
delete p;
aa++;//后置自加产生新节点
cout<<aa.a<<endl;
cout<<aa.next->a<<endl;
p=&aa;
p=++*p;//该行语句与p=p->next等效;
}
从以上两段代码可以知道,运算符重载时其操作数至少有一个为自定义类型,且是该类型的对象,而不能是指针。
如上代码中,”+”的重载只需声明一个任意已声明类型的参数即可,对于双目运算符,仅需声明一个运算符,重载该运算符的类型被默认为该运算符的一个操作数,且该操作数是该重载类型的对象。
对于“++”运算符,由于它是单目运算符,所以声明时不需另外指明操作数类型,且仅以()表示前置,以(int)表示后置;
昨天的代码中之所以“++”重载的声明和定义都没有错但是并有执行,是因为代码中的声明是 lianbiao *p=&aa;
++p;
这样p是一个指向链表类型的指针,所以程序执行过程中以p的类型为对象的类型,跳过p所包含的存储长度(8个字节),所以昨天的输出结果上显示十六进制地址值相差了8;
因为p是一个lianbiao类型的指针,而重载的“++”操作数是lianbiao类型的对象,所以程序不执行以上代码重载的操作;如果改写为++*p即可实现重载。
以上可见,以重载运算符“++”的方法不能像对一个整形数的自加1操作( int a++)那样直接实现链表的p=p->next操作,但是可以间接成为
p=++*p;而通过对象方法 classtype a.next=++a 或重载“--”可以实现链表的节点删除