当前位置:文档之家› 第十三章 运算符重载

第十三章 运算符重载


CArray::CArray(int n) { if(n>0){ arp=new int[n]; memset(arp,0,sizeof(int)*n); //string.h len=n; } else{ len=0;arp=0;} }
int & CArray::operator[](int index) {
数组下标运算符[ 5. 数组下标运算符[ ] 重载下标运算符的一般格式为: <类型> operator[ ](<参数>) {…} //函数体 其中<参数>为一个参数,且仅有一个 参数,该参数设定了下标值,通常为整 型。 下标运算符必须利用类的成员函数来实 现,而不能使用友元函数。
class ainteger { 【例1】下标是否越界的检验 下标是否越界的检验 int *a; int sz; public: ainteger ai(10); ainteger( int size) ai[2]=3; { sz=size; int i=ai[2]; a=new int[size]; } int & operator[ ](int i ) { if(i<0 || i>=sz) ai.operator[](2) { cout<<“error”<<endl; 返回ai::a[2]的引用 exit(1); } return a[i]; } ~ainteger ( ) { delete [ ]a; } };
【例】利用类的缺省赋值运算符产生的指针悬挂问题 class CA { char *ps; public: CA(){ps=0;} CA(char *s) { ps=new char[strlen(s)+1]; strcpy(ps,s); } ~CA(){if(ps) delete[]ps;} char *GetS(){return ps;} };
程序编译没有问题,但运行时出错!
缺省赋值语句产生指针悬挂问题示意图。
s1 s2 s1=s2 “China!” “Computer!” “China!” “Computer!” s1 s2
无法撤消 s1 撤消s2 “China!” “Computer!” 已不存在 指针悬挂 撤消s1 出错
此时在类CA中可以对赋值运算符进行如下重载。
【例2】对下标运算符进行重载,使之具有检查下 对下标运算符进行重载, 对下标运算符进行重载 标是否越界的功能 class Carray { int len; int *arp; public: CArray(int n=0); ~CArray() {if (arp) delete[]arp;} int & operator[] (int index); // 定义重载的下标运算符 };
void main(void) { CA s1("China!"),s2("Computer!"); cout<<"s1="<<s1.GetS()<<'\t'; cout<<"s2="<<s2.GetS()<<'\n'; s1=s2; //A产生指针悬挂 //A产生指针悬挂
cout<<"s1="<<s1.GetS()<<'\t'; cout<<"s2="<<s2.GetS()<<'\n'; }
乘号* 利用成员函数重载) 利用成员函数重载 2. 乘号* (利用成员函数重载 C C:: operator*(C m ) { C temp; temp.x=x*m.x; return temp; } C a,b; C c=a*b; a.operator*(b)
乘号* 利用友元函数重载) 利用友元函数重载 2. 乘号*(利用友元函数重载 先在类中声明: friend C operator*(C ,C); 再在类外定义: C operator*(C m1, C m2 ) { C temp; temp.x=m1.x*m2.x; return temp; } C a,b; C c=a*b; Operator*(a,b)
后置运算符-- 利用友元函数重载) 利用友元函数重载 3. 后置运算符-- (利用友元函数重载 class C{ private: double x; C A(1); public: A--; C( ) { x=0.0; } C(double a) { x=a; } friend C operator--(C &,int); }; 整型参数没有 C operator--(C &t,int) 特别的意义,只是 特别的意义, { t.x--; 标识重载的是后置 运算符。 运算符。 return t; }
二.双目运算符重载
加号+ 利用成员函数重载) 利用成员函数重载 1. 加号+ (利用成员函数重载 C C:: operator+(C m ) { C temp; temp.x=x+m.x; return temp; } C a,b; C c=a+b; a.operator+(b)
加号+ 利用友元函数重载) 利用友元函数重载 1. 加号+ (利用友元函数重载 先在类中声明: friend C operator+(C ,C); 再在类外定义: C operator+(C m1, C m2 ) { C temp; temp.x=m1.x+m2.x; return temp; } C a,b; C c=a+b; operator+(a,b)
一.单目运算符重载
负号“ 利用成员函数重载 1. 负号“-” (利用成员函数重载 利用成员函数重载) C C:: operator - ( ) { C temp; temp.x=-x; return temp; } C c=-a; a.operator-( )
负号“-” (利用友元函数重载 利用友元函数重载 1. 负号 利用友元函数重载) class C{ //… public: friend C operator-(const C); //… }; C operator- (const C m ) { C temp; temp.x=-m.x; return temp; } C c=-a; operator-(a)
利用成员函数重载 3. 后置运算符-- (利用成员函数重载 利用成员函数重载) class C{ private: double x; C A(1); public: A--; C( ) { x=0.0; } C(double a) { x=a; } 整型参数没有 C operator--(int) 特别的意义,只是 特别的意义, { x--; 标识重载的是后置 return *this; 运算符。 运算符。 } };
void main(void) { CArray m1(10),m2(3); int i; // for(i=0;i<10;i++) m1[i]=i; / 重载数组下标的使用 for(i=1;i<11;i++) cout<<m1[i]<<" cout<<'\n'; m2[2]=26; cout<<"m2[2]="<<m2[2]<<'\n'; } "; //B //C
CA & CA::operator=(CA &b) { if(ps) dele [strlen(b.ps)+1]; strcpy(ps,b.ps); } else ps=0; return *this; }
对赋值运算符进行重载时要注意以下三点: 一是只能利用成员函数重载,不能用 友元函数重载; 二是重载的赋值运算符不能被继承; 三是不能将赋值运算符重载函数声明 为虚函数。
C a(10), b(3); 希望c=a+b; 希望 加法运算符重载函数(利用成员函数重载) 利用成员函数重载 利用成员函数重载 class C{ //…… public: C operator+(C m) //定义方式 { C temp(x+m.x); return temp; } //…… }; C a(10), b(3), c; a.operator+(b) c=a+b; 赋值运算符一般用预定义的 C c=a.add(b);
单目运算符重载中成员函数重载与友元函 数重载之间的区别: 用成员函数重载单目运算符,由于此时 运算符的操作数为当前对象,因此用成员 函数重载单目运算符时无参数。 由于友元函数非成员函数,不能使用 this指针,因此用友元函数重载单目运算 符时必须带有一个参数作为该运算符的操 作数。
前置运算符++ 利用成员函数重载) 利用成员函数重载 2. 前置运算符++ (利用成员函数重载 class C{ private: double x; C A(1); public: C( ) { x=0.0; } ++A; C(double a) { x=a; } C operator++() { x++; return *this; } };
第十三章 运算符重载
运算符——一种函数;对于类对象,用户可重新定义运算符函数。
引 子
class C{ private: double x; public: C( ) { x=0.0; } C(double a) { x=a; } C add(const C m) { C temp; temp.x=m.x+x; return temp; } };
相关主题