第11章 友元与运算符重载(6)

2019-03-09 14:35

第11章 友元与运算符重载 ·300·

}

形参为String类的引用s。在函数体内先删除当前字符串内容。然后将形参字符串长度赋给当前对象的字符串长度Length。将形参字符串内容赋给当前对象。

(3)因为字符串“+”运算符重载函数为友元函数,因此参加运算的两个字符串必须以形参方式输入函数体内,所以重载函数的形参为两个String类型的对象的引用。函数体内先定义一个String类型的临时对象t,用于存放两个字符串拼接的结果。再将两个字符串的长度之和赋给t的长度t.Length,用new运算符动态分配长度为t.Length+1的内存空间,并将其地址赋给t.Sp。再用strcopy()函数将s1拷贝到t,用strcat()将s2拼接到t中,完成t=s1+s2的字符串拼接工作,最后将t返回给调用对象。由于函数返回值为对象t,所以,重载函数的返回类型为String。如图11.5所示。

s1.Sp→ “s” “o” ? “e” “\\0”

s2.Sp→

s1.Length=8

“d” “e” ? “n” “\\0”

t.Sp→

s2.Length=6

“s” “o” ? “n” “\\0”

t.Length=14

图11.5 字符串“+”运算符拼接运算示意图

(4)在主函数中:

字符串赋值运算语句s5=s2;被编译器解释为对“=”运算符重载函数的调用:s5.opreator=(s2);

字符串拼接运算语句s6=s4+s3;被编译器解释为对“+”与“=”运算符重载函数的调用:s6.opreator=(opreator+(s4,s3));

字符串比较运算语句s4>s5;被编译器解释为对“>”运算符重载函数的调用:s4.opreator>(s5);

11.2.6 赋值运算符和赋值运算符重载

在相同类型的对象之间是可以直接赋值的,在前面的程序例子中已多次使用。但当对象的成员中使用了动态数据类型时,就不能直接相互赋值,否则在程序执行期间会出现运算错误。

【例11.13】对象间直接赋值导致程序执行的错误。

# include # include class String { private:

char *ps; public: String() {ps=0;}

第11章 友元与运算符重载

String(char * s)

{ ps =new char [strlen(s)+1]; strcpy(ps,s); }

~String()

{ if (ps) delete [] ps;} char * GetS() { return ps;} };

void main (void ) {

String s1(\ cout<<\ cout<<\ s1=s2;

cout<<\ cout<<\ char c; cin>> c; }

程序执行后输出:

s1=China! s2=Computer! s1=Computer! s2=Computer!

·301·

程序执行到cin>>c语句输入任意字符(如:a)时发生错误,这是因为执行s1=s2后 ,使s1、s2中的ps均指向字符串“Computer!”,当系统撤消s1时调用析构函数回收了ps所指的字符串存储空间,当撤消s2调用析构函数时,已无空间可回收,出现错误。

解决上述错误的方法是用重载运算符“=”。在上例的类String中应增加如下的赋值运算符重载函数:

String & operator= (String &b) { if (ps) delete [] ps; if (b.ps)

{ ps= new char [strlen(b.ps)+1]; strcpy(ps,b.ps); }

else ps=0; return * this; }

第11章 友元与运算符重载 ·302·

11.3 多态性与虚函数 11.3.1多态性技术

1.多态性技术的概念

函数重载是指用同名函数完成不同的函数功能,例如:编写求两实数最大值与两整数最大值的同名函数Max()如下:

float Max(float a,float b) {return a>b?a:b;} int Max(int a,int b) {return a>b?a:b;} main()

{ cout<

在上例中,调用函数Max(1.2,4.5)中的实参为实数时,系统会根据实参类型自动调用求两实数最大值的函数。而调用函数Max(1,4)中实参为整数时,系统会自动调用求两整数最大值函数。即:用同名函数完成了求实数最大值与求整数最大值的问题,当用户在调用函数Max()的实参中给出实数则求实数的最大值,给出整数则求出整数的最大值。无疑函数重载给用户带来了使用上便利。

运算符重载是指用同名运算符完成不同的运算操作。例如:编写求两复数和的“+”运算符重载函数:

Complex operator+(Complex &c) { Complex temp;

temp.Real=Real+c.Real; temp.Image=Image+c.Image; return temp; }

void main(void)

{ Complex c1(10,20),c2(15,30),c3; c3=c1+c2;

float a1=10,a2=20,a3; a3=a1+a2; }

在上例中表达式c1+c2 将解释为对“+”运算符重载函数的调用:c1.operator+(c2) ; 而算术表达式a1+a2 则完成普通算术加法操作。显然,运算符重载使得用户可用同名运算符“+”完成不同数据类型变量的加法操作,这给用户使用带来了具大的方便。

以上所述函数重载与运算符重载就是C++中的多态性技术,所谓多态性技术是指调用同名函数完成不同的函数功能,或使用同名运算符完成不同的运算功能。它常用重载技术

第11章 友元与运算符重载 ·303·

与虚函数来实现。在C++中,将多态性分为两类:编译时的多态性和运行时的多态性。

2.编译时的多态性

编译时的多态性是通过函数的重载或运算符的重载来实现的。函数的重载是根据函数调用时,给出不同类型的实参或不同的实参个数,在程序执行前就能确定调用哪一个函数。对于运算符的重载,是根据不同的运算对象在编译时就可确定执行哪一种运算。如在上例中的“+”运算:c3=c1+c2 与 a3=a1+a2,根据参加“+”运算对象是复数c1、c2还实数a1、a2,就可确定是调用复数加法重载函数还是进行普通实数的加法运算。

3.运行时的多态性

运行时的多态性是指在程序执行前,根据函数名和参数无法确定应该调用哪一个函数,必须在程序执行过程中,根据具体执行情况来动态地确定。这种多态性是通过类的继承关系和虚函数来实现的,主要用于实现一些通用程序的设计。

11.3.2 虚函数

在基类中用关键字 virtual修饰的成员函数称为虚函数,虚函数的定义格式为: virtual <类名> <函数名>(参数) {函数体}

用虚函数实现“运行时多态性”的方法是:在派生类中定义与基类虚函数同名同参数同返回类型的成员函数,在派生类中定义的这个成员函数也称为虚函数。虽然基类中的虚函数与各派生类中虚函数同名同参数,但由于各虚函数的函数体是不同,因而可用同名虚函数在运行时完成对不同对象的操作,从而实现“运行时多态性”。下面举例说明用虚函数实现“运行时多态性”的方法:

【例11.14】定义基类High,其数据成员为高H,定义成员函数Show()为虚函数。然后再由High派生出长方体类Cuboid与圆柱体类Cylinder。并在两个派生类中定义成员函数Show()为虚函数。在主函数中,用基类High定义指针变量p,然后用指针p动态调用基类与派生类中虚函数Show(),显示长方体与圆柱体的体积。

# include class High { protected: float H; public:

High(float h) { H=h;}

virtual void Show()

//在基类中定义虚函数Show()

{ cout<<\};

class Cuboid:public High { private:

float Length,Width; public:

第11章 友元与运算符重载 ·304·

Cuboid(float l=0,float w=0,float h=0):High(h) { Length=l; Width=w;} void Show() //在长方体派生类中定义虚函数Show() { cout<<\ cout<<\ cout<<\

cout<<\olume=\ } };

class Cylinder:public High { private: float R; public:

Cylinder(float r=0,float h=0):High(h) {R=r;}

void Show() //在圆柱体派生类中定义虚函数Show() { cout<<\ cout<<\

cout<<\olume=\ } };

void main(void) { High h(10),*p;

Cuboid cu(10,10,10); Cylinder cy(10,10); h.Show(); cu.Show(); cy.Show(); p=&h; p->Show(); p=&cu; p->Show(); p=&cy; p->Show(); }

执行程序后输出:

High=10 Length=10

Width=10

High=10

Cubiod Volume=1000


第11章 友元与运算符重载(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2016注册咨询后续教育-城市轨道交通线网规划

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: