第8章多态性与虚函数
private:
double x,y;
//点坐标
};
class Line: public Point{
double x1,y1;
//增加终点坐标成员
public:
Line(double i1,double j1,double i2,double j2):Point(i1,j1)
{ x1=i2; y1=j2; }
3. 虚函数与动态多态
虚函数是一种成员函数,而且是非static的成员函数。
一个函数被说明或定义为虚函数后,说明表示它在派 生类中可能有多种不同的实现。
虚函数只能通过指针或引用所表示的对象来调用。
构造函数不允许为虚函数,但析构函数允许为虚函数, 以便能自动释放由指针或引用所表示的对象。
例:不使用虚函数的静态联编示例。 结果: 0 0 0
例题:构造函数重载: #include <iostream.h> class classA { public: classA( ){a1=0;a2=0;cout<<”default\n”; }
classA(int i,int j); void print( ){ cout<<a1<<”,”<<a2<<endl; } ~A( ) { cout<<”destructure\n”; } private: int a1,a2; }; classA::classA(int i,int j) { a1=i; a2=j; cout<<”constructure\n”; } void main() { classA ob1,ob2(12,8); ob1.print( ); ob2.print(); }
private: double real,imag;
}; complex complex:: operator+(const complex &a) { return complex(real+a.real,imag+a.imag); }
void complex::display() { cout<<"("<<real<<", "<<imag<<"i)"<<endl; }
#include <iostream.h> #include <string.h>
成员函数重载例题:
class string
{ public: string(char *pa);
void print( ) { cout<<pstr<<endl; }
void print(char *str) { cout<<str<<endl; }
的运算符;
重载运算符时不能改变原运算符操作数的个数、原有
运算符的优先级和结合性,也不能改变原运算符对 于内部基本类型对象的含义;
如果重载了某个运算符(如“=”),并不意味着重载了
相关的运算符(如“+=”、“-=”等);
运算符重载:
运算符重载函数的实现: 可以利用: 成员运算符函数 友元运算符函数
学习时注意:不同的实现方法,参数的 个数不同。
例:利用友元函数实现两个复数相加运算。
#include <iostream.h> class complex{
public: complex(double r=0,double i=0){real=r;imag=i;} friend complex operator+(const complex &a,const complex & void display();
}
2. 运算符重载 运算符重载: 将已有的运算符赋予新的含义。
不可重载的运算符
“•”
圆点运算符
“•*” 成员指针选择运算符
“∷” 域分辨运算符
“?:” 条件运算符
“sizeof” 长度运算符
除以上五个运算符外,其余运算符均可重载。
运算符重载:
重载运算符的规则:
只能重载C++中已有的可重载的运算符,不能建立新
程序说明:
友员函数
friend complex operator+( const complex &a,const complex &b)
复数类对象相加:c1+c2, 相当于:operator+(c1,c2)
注意:用友元函数 operator+( ) 必须有两个参数。
单目运算符重载例题: 重载++、- -、=,同时实现2个变量的加1、减1。
};
class Line:public Point{
double x1,y1;//增加终点坐标成员public:
Line(double i1,double j1,double i2,double j2):Point(i1,j1)
{ x1=i2; y1=j2;}
double Area( ) { return 0.0; }
虚函数:
虚函数是类中的成员函数。 虚函数的一般格式如下: virtual 类型名 函数名(形参表) { 函数体 }
虚函数说明:
•一个函数被说明或定义为虚函数后,表明它
在派生类中可能有多种不同的实现,即重新定 义。
•在派生类中重新定义时,其函数原型,包括
返回类型、函数名、参数个数和类型以及各参 数顺序,都必须与基类中的原型完全相同。否 则,将处理为静态联编。
#include <iostream.h>
class count
{ int a,b;
public:count(int i,int j){ a=i; b=j; }
void show( ){ cout<<a<<“ “<<b<<endl;}
void operator++( );
void operator - -( );
第8章 多态性与虚函数
本章内容
多态性概述 运算符重载 虚函数及动态多态性
1. 多态性概述
多态性是面向对象程序设计的一个重要特征。
• 多态性:是指发出同样的消息被不同类型的对象
接收时而导致不同的行为。
•多态是指类中具有相似功能的不同函数使用同一
个名称。当调用这个相同名称的函数时,可根据需 要完成不同的功能.
};
class Circle:public Point{
虚函数:
基类对象与派生类对象之间的赋值兼容性表现在:
把派生类对象赋给基类对象
A a1; B b1; a1=b1;
用派生类对象向基类对象的引用赋值或初始化
A a1; B b1; A &r1=a1; r1=b1; A &r2=a2;
把派生类对象的地址赋给基类对象的指针变量
{cout<<"("<<real<<", "<<imag<<"i)"<<endl;} void main(){
complex c1(3,4),c2(5,-10),c3; c3=c1+c2; c1.display();cout<<"+";c2.display();cout<<"=";c3.display(); co
上例函数fun()的形参也可以是如下形式:
void fun(Point &p)
{ cout<<p.Area()<<endl; }
main( )函数也要相应改成如下形式:
void main( ){ Line lin(1,3,4,5); //定义线对象 fun(lin); Circle cir(10,3,6); //定义圆对象 fun(cir); Rectangle rec(7,8,2,5); //定义矩形对象 fun(rec); }
virtual double Area(){ return 0.0; } //定义虚函数
};
程序说明:
各派生类中重定义的虚函数仍是虚函数,不 管是否有virtual。
虚函数的调用 在main()中定义指向根基类的指针p可以指
向派生类对象。
在执行过程中,可根据指针p的当前指向而 调用相应类的虚函数,从而实现动态的多态 性。
1. 多态性
从实现时机方面讲,多态性可以分为: 静态多态性 动态多态性
静态多态性 : 指可在编译期间确定的多态性。 静态多态性: 函数重载 运算符重载
动态多态性: 指在程序在运行过程中,才能确定的多 态性。
静态多态性:
1)函数重载:几个函数具有相同的名字,但函数参数 的个数或类型不同。
重载的函数可以是: 一般函数 类中的成员函数、构造函数
void main(){ complex c1(3,4), c2(5,-10), c3;
程序说明: 成员函数
complex operator+(const complex &a) 用于定义“+”运算符重载 复数类对象相加: c1+c2,
相当于 : c1.operator+ (c2)
运算符重载:
private: char *pstr;
};
string::string(char *pa)
{ pstr=new char[strlen(pa)+1]; strcpy(pstr, pa);
}