您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 第7章多态性与虚函数.
第七章多态性与虚函数本章内容多态性概述运算符重载虚函数多态性多态性是面向对象程序设计的一个重要特征。多态性:是指发出同样的消息被不同类型的对象接收时而导致不同的行为。所谓发消息就是调用类中的成员函数。多态的实现•函数重载•运算符重载•虚函数静态联编和动态联编联编的含义是指把一个消息和一个方法联系在一起,也就是把一个函数名与其实现代码联系在一起。静态联编是在编译阶段进行的。动态联编是在程序运行过程中,根据程序运行的需要进行的联编。当通过对象名调用成员函数时,只可能是调用对象自身的成员,所以,这种情况可采用静态联编实现。当通过基类指针调用成员函数时,由于基类指针可以指向该基类的不同派生类对象,因此存在需要动态联编的可能性,但具体是否使用动态联编,还要看所调用的是否是虚函数。静态多态性与动态多态性静态多态性(静态联编、静态绑定)•联编工作出现在编译阶段。•用对象名或者类名来限定要调用的函数,只能是调用对象自身的成员动态多态性(动态联编、动态绑定)•联编工作在程序运行时执行•用基类指针或者引用来限定要调用的函数。•在程序运行时根据基类指针指向的对象才能确定将要调用哪个类的成员函数。静态联编和动态联编联编的含义是指把一个消息和一个方法联系在一起,也就是把一个函数名与其实现代码联系在一起。何时将一个变量与其实际类型所定义的行为绑定。在编译期绑定,属于静态联编或静态绑定;在运行期绑定,属于动态联编或动态绑定7静态联编/绑定(StaticBinding)classMyclass{public:...function();function(int);function(int,int);...};voidmain(){Myclassa(5);a.function(7);…}用一个成员函数实现两个复数相加运算规则:•实部和虚部分别相加。操作数:•两个操作数都是复数类的对象。复数类名:Complex成员函数:complex_add()//实部和虚部分别相加display()//输出复数的实部和虚部classComplex{public:Complex();Complex(doubler,doublei);Complexcomplex_add(Complex&a);//实部和虚部分别相加voiddisplay();//输出复数的实部和虚部private:doublereal,imag;};classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}Complexcomplex_add(Complex&a);voiddisplay();private:doublereal,imag;};ComplexComplex::complex_add(Complex&a){Complextemp;temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}temp.real=this-real+a.real;temp.imag=this-imag+a.imag;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;voidComplex::display(){cout(real,imagi)endl;}voidmain(){Complexc1(3,4),c2(5,-10),c3;c3=c1.complex_add(c2);coutc1=;c1.display();coutc2=;c2.display();coutc1+c2=;c3.display();}程序输出的结果为:c1=(3,4i)c2=(5,-10i)c3=c1+c2=(8,-6i)问题如何处理对象1+对象2?14计算机怎样处理运算符intnum1,num2,num3;num3=num1+num2;C++将各种运算符都处理成一个“运算符函数”调用15计算机怎样处理运算符intnum1,num2,num3;num3=num1+num2;计算机这样处理运算符:num3=operator+(num1,num2);intoperator+(inti,intj){returni+j;}16计算机怎样处理运算符doublenum1,num2,num3;num3=num1+num2;计算机这样处理运算符:num3=operator+(num1,num2);doubleoperator+(doublei,doublej){returni+j;}17计算机怎样处理运算符intnum1,num2,num3;num3=num1+num2;计算机这样处理运算符:operator=(num3,operator+(num1,num2));18重载+运算符我们打算重载运算符用于对复数类的对象的操作Complexnum1,num2,num3;num3=num1+num2;Thecomputerthinksofitas:num3=operator+(num1,num2);Complexoperator+(Complexi,Complexj){......}运算符重载的实质运算符重载是对已有的运算符赋予新的含义必要性•C++中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)•重载运算符主要用于对类的对象以同样的形式按重新定义的方式操作实现机制是一种特殊函数的重载。运算符重载运算符重载有两种形式:表达式:左操作数+右操作数重载为类的成员函数左操作数.operator+(右操作数)重载为类的友元函数operator+(左操作数,右操作数)将运算符重载函数说明为类的成员函数格式如下:class类名{......返回类型operator运算符(形参表);......};类型名类名::operator运算符(形参表){函数体}说明:重载二元运算符时,参数表中应有一个形参。重载一元运算符时,参数表应为空(后置++、--除外)。将“+”运算重载为复数类的成员函数规则:•实部和虚部分别相加。操作数:•两个操作数都是复数类的对象。classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}Complexoperator+(Complex&a);voiddisplay();private:doublereal,imag;};ComplexComplex::operator+(Complex&a){Complextemp;temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}voidComplex::display(){cout(real,imagi)endl;}voidmain(){Complexc1(3,4),c2(5,-10),c3;c3=c1+c2;//相当于c1.operator+(c2);coutc1=;c1.display();coutc2=;c2.display();coutc1+c2=;c3.display();}ComplexComplex::operator+(Complex&a){Complextemp//显式说明局部对象temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}c1+c2;比较下面两种写法细解运算符重载ComplexComplex::operator+(Complex&a){returnComplex(real+a.real,imag+a.imag);}ComplexComplex::operator+(Complex&a){Complextemp//显式说明局部对象temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}00temprealimagc1+c2;细解运算符重载ComplexComplex::operator+(Complex&a){Complextemp//显式说明局部对象temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}-68temprealimagc1+c2;细解运算符重载ComplexComplex::operator+(Complex&a){Complextemp//显式说明局部对象,调用构造函数temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}-68temprealimag-68realimagc1+c2;临时对象细解运算符重载生成一个临时对象调用拷贝构造函数细解运算符重载:ComplexComplex::operator+(Complex&a){Complextemp//显式说明局部对象temp.real=real+a.real;temp.imag=imag+a.imag;returntemp;}-68realimagc1+c2;tempgoesaway临时对象ComplexComplex::operator+(Complex&a){returnComplex(real+a.real,imag+a.imag);}用隐式的临时对象替换显式的对象temp-68临时对象realimag在return后面跟的表达式中调用的是类的构造函数,它创立了一个临时对象,返回值就是该临时对象。书上是这样写的,比前面的方法效率高。这里采用Complex对象的引用而不是对象本身,调用时不再重新分配内存建立一个复制的对象,函数效率会更高。而在引用形式参数类型说明前加const关键字,表示被引用的实参只可读而不可改变。ComplexComplex::operator+(constComplex&a){returnComplex(real+a.real,imag+a.imag);}将运算符重载函数说明为类的友元函数格式如下:class类名{......friend返回类型operator运算符(形参表);......};重载二元运算符时,参数表中应有两个形参。重载一元运算符时,参数表应有一个形参。运算符重载由于友元函数没有隐含指向当前对象的this指针,所以,一个单目运算符重载为类的友元函数时,其参数个数为1个;一个双目运算符重载为类的友元函数时,其参数个数必须为2个。例:利用友元函数实现两个复数相加运算。#includeiostream.hclassComplex{public:Complex(doubler=0,doublei=0){real=r;imag=i;}friendComplexoperator+(constComplex&a,constComplevoiddisplay();private:doublereal,imag;};Complexoperator+(constComplex&a,constComplex&b){returnComplex(a.real+b.real,a.imag+b.imag);}voidComplex::display(){cout(real,imagi)endl;对单目运算符,当以成员函数形式重载运算符时没有参数,以友元函数形式重载运算符时有一个参数;对双目运算符,当以成员函数形式重载运算符时有一个参数;以友元函数形式重载运算符时有两个参数;运算符重载小结两种重载形式的比较对于单目运算符、复合赋值运算符“+=、-=、/=、*=”等常选择用成员函数重载。对于运算符“=、()、[]、-”只能选择用成员函数重载。对于其他运算符,如“+、-、*、/”等双目运算符,常常选择用友元函数重载,以适应更多的计算形式。对于复数类对象相
本文标题:第7章多态性与虚函数.
链接地址:https://www.777doc.com/doc-2111781 .html