第五章 多态性和虚函数
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
A& A::operator = (A &p) { X = p.X; Y = p.Y; cout << "Assigment operator called.\n"; return *this; } void main( ) { A a(7, 8); A b; b = a; cout << b.getX( ) << "," << b.getY( ) << endl; } IC-MSP V1.0
void display(); private: double real;double imag; }; void complex::display() {cout<<“(“<<real<<“,”<<imag”)”<<endl;} complex operator +(complex c1,complex c2) {return complex(c2.real+c1.real,c2.imag+c1.imag);} complex operator –(complex c1,complex c2) {return complex(c1.real-c2.real,c1.imag-c2.imag);} IC-MSP V1.0
IC-MSP V1.0
函数重载方式2
2. 基类成员函数在派生类中重载 在基类和派生类中的重载函数时,编译时根据下 面两种形式区分: (1)使用“类名::”加以区分 (2) 根据调用函数对象加以区分。
IC-MSP V1.0
示例
#include <iostream.h> class point { int x,y; public: point(int x,int y) { point::x=x; point::y=y; } float area() {return 0.0;} }; class circle:public point { int r; public: circle(int x,int y,int r1):point(x,y) { r=r1;} float area(){ return 3.14*r*r;} }; void main() { point p1(10,10); circle c1(5,5,10); cout << p1.area() << "\n"; //根据调用函数对象加以区分 cout << c1.area() << endl; cout << c1.point::area() << endl;//使用“类名::”加以区分 }
};
IC-MSP V1.0
那么可以这样定义两个复数类的对象: complex a(10,20),b(5,8); 那么用a+b是否可以得到这两个复数的和呢?
IC-MSP V1.0
运算符重载概述
运算符重载的规则如下:
几乎所有的运算符都可以用作重载,下列运算符不允许重 载:.,*,:: ,?:,# 重载之后运算符的优先级和结合性都不会改变。 运算符重载是针对新类型数据的实际需要,对原有运算符 进行适当的改造。一般来讲,重载的功能应当与原有功能 相类似,不能改变原运算符的操作对象个数,同时至少要 有一个操作对象是自定义类型。
IC-MSP V1.0
函数重载
函数重载 C++语言中,只要在声明函数原型时形式参数 的个数或者对应位置的类型不同,两个或更多的 函数就可以共用同一个名字。这种在同一作用域 中允许多个函数使用同一函数名的措施称为重载。 函数重载的方法
int abs(int x){…} double abs(double x){…} long abs(long x){…} main(){ abs(-5); abs(-5L); abs(3.14); } IC-MSP V1.0
手机移动设备嵌入式C++
第五章 多态性和虚函数
IC-MSP V1.0
回顾
基类和派生类 单继承 多继承 虚基类
IC-MSP V1.0
目标
多态的概念 函数重载 运算符重载
了解静态联编和动态联编
虚函数
理解抽象类的概念和用法
IC-MSP V1.0
多态性的基本概念
程序的多态性
比如:C语言中的运算符”/”对于不同的数据类型具有 不同的含义。 6/4=1 6.0/4=1.5 6/4.0=1.5 6.0/4.0=1.5 程序中同一符号或名字在不同情况下具有不同解释的现 象称为多态性。
IC-MSP V1.0
重载为友元函数
重载为友元函数的定义格式如下: friend <类型说明符> operator <运算符> (< 参数表 >) {……} 表达式 c1 + c2 被编译程序解释为: operator+(c1,c2) 当重载友元函数时,将没有隐含的参数 this 指针 对双目运算符,友元函数有两个参数;对单目运算符,友 元函数有一个参数 不能重载为友元函数的运算符是:=,(),[ ]和 ->
ຫໍສະໝຸດ Baidu
IC-MSP V1.0
运算符重载
IC-MSP V1.0
问题的提出
C++中预定义的运算符的操作对象只能是基本数据类型,如 果我们要想用“+”来实现两个复数的求和运算,怎么来实现呢? 比如说:我们定义了一个复数类complex
class complex {public:complex(double r=0.0,double I=0.0) {real=r;imag=I;} void display(); private: double real; double imag;
面向对象的多态:
在面向对象中,多态性是指发出同样的消息被不同类型 的对象接收时导致完全不同的行为
IC-MSP V1.0
多态的种类
1. 编译时多态 是指在程序编译阶段即可确定下来的多态性,主要通 过重载机制获得。包括函数重载和运算符重载。 2. 运行时多态 是指必须等到程序动态运行时才可确定的多态,主要 通过继承结合虚函数来完成的。普通函数使用静态绑定, 而虚函数使用动态绑定。
实例(续)
complex complex::operator +(complex c2) {//当使用成员函数重载运算符时,双目运算符仅有一个参数,//与一般成员函数一
样,运算符函数中隐含有this指针,用于指向//调用该成员函数的对象。
return complex(real+c2.real,imag+c2.imag); }//创建一个临时无名对象作为返回值 complex complex::operator –(complex c2) { return complex(real-c2.real,imag-c2.imag); } void complex::display() {
赋值运算符重载
#include <iostream.h> class A { public: A( ){X = Y = 0;} A(int i, int j){X = i; Y = j;} A(A &p){X = p.X; Y = p.Y;} A& operator = (A &p); int getX( ){return X;} int getY( ){return Y;} private: int X, Y; }; IC-MSP V1.0
IC-MSP V1.0
函数重载应注意问题
不要使用重载函数来描述毫无相干的函数 构造函数可以重载,普通成员函数也可以重载
如果两个函数的参数表相同,但是返回类型不同,则第一个声明被视为第一 个的错误重复声明,会被标记为编译错误
• •
unsigned int Max( int i1, int i2 ); int Max( int , int ); // 错误:只有返回类型不同 在重载函数中使用缺省函数参数时应注意调用的二义性,例如: void print(int a, int b) { cout << "a=" << a << ",b=" << b << endl; } void print(int a, int b, int c = 50) { cout << "a=" << a << ",b=" << b << endl; } 下列函数调用,由于二义性将通不过: print(10,100);
void main() {complex c1(5,4),c2(2,10),c3; cout<<“c1=”;c1.display(); cout<<“c2=”;c2.display(); c3=c1-c2; cout<<“c3=c1-c2=”; c3.display(); c3=c1+c2; cout<<“c3=c1+c2=”; c3.display(); } IC-MSP V1.0
cout<<"("<<real<<","<<imag<<")"<<endl;
}
IC-MSP V1.0
实例(续)
void main() { complex c1(5,4),c2(2,10),c3; cout<<“c1=”;c1.display(); cout<<“c2=”;c2.display(); c3=c1-c2; //c1.operator-(c2); cout<<“c3=c1-c2=”; c3.display(); c3=c1+c2; //c1.operator +(c2) cout<<“c3=c1+c2”; c3.display(); }
IC-MSP V1.0
示例
例:复数类加减法运算重载-友元函数形式 #include <iostream.h> class complex { public: complex(double r=0.0,double i=0.0) {real=r;imag=i;}
friend complex operator +(complex c1,complex c2); friend complex operator –(complex c1,complex c2); IC-MSP V1.0
运算符重载
1. 重载为类的成员函数
重载函数为类的成员函数的格式如下: <类名> operator <运算符>(<参数表>) 表达式 c1 + c2 被编译程序解释为: c1.operator+(c2) 重载函数为类成员函数时,总隐含了一个参数,该参数 为this指针 对双目运算符,有一个参数;对单目运算符,不再显式 说明参数 IC-MSP V1.0
实例(续)
#include <iostream.h> class complex { public: complex(double r=0.0,double i=0.0) {real=r;imag=i;} complex operator +(complex c2); complex operator -(complex c2); void display(); private: double real; double imag; }; IC-MSP V1.0
两种重载形式的比较
单目运算符最好被重载为成员函数;对双目运算符最好 被重载为友元函数 考虑一个表达式: 5.67 + c 重载为友元函数时,该表达式将被解释为: operator+(complex (5.67), c) V 重载为成员函数时,该表达式将被解释为: 5.67.oprator+(c) X 有的双目运算符重载为成员函数为好,例如,赋值运算 符 IC-MSP V1.0
IC-MSP V1.0
运算符重载的实现
运算符的重载形式有两种:
重载为类的成员函数
重载为类的友元函数。 运算符重载为类的成员函数的语法形式如下: <函数类型> operator <运算符>(<形参表>) { <函数体>; } friend <函数类型> operator <运算符>(<形参表>) { <函数体>; } IC-MSP V1.0
函数重载方式1
1. 在一个类中说明的重载
在一个类中说明的重载函数之间靠所带参数个数或参数类型的不同加以区分
class point { int x,y; public: point(){x=0;y=0;} point(int x,int y) { point::x=x;point::y=y;} point(int i) { x=y=i;} }; void main() { point p1; point p2(2,3); point p3(6); }