重载和多态
重载与多态
多态的概念
多态是指同样的消息被不同类型的对象接收时导致不同的行为,所谓的消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数。
运算符的重载
运算符在类内的重载:
#include<iostream>
using namespace std;
class Complex{
public:
Complex(float a=0,float b=0):real(a),imag(b){};//初始化复数
Complex operator+ (const Complex &c2) const;//重载+号
void display(){//展示函数
cout<<real<<"+"<<imag<<"i"<<endl;
}
private:
float real,imag;
};
Complex Complex::operator+(const Complex &c2)const{//定义这个重载函数
return Complex(real+c2.real,imag+c2.imag);
}
int main(){
Complex c1(5,4),c2(2,2),c3;//定义三个对象
c3 = c1 + c2;//运用重载运算符+号
c3.display();//展示出来
}
运行结果如下
运算符在类外的重载
#include<iostream>
using namespace std;
class Complex{
public:
Complex(float a=0,float b=0):real(a),imag(b){};
void display(){
cout<<real<<"+"<<imag<<"i"<<endl;
}
friend Complex operator-(const Complex &c1,const Complex &c2);//用友元函数在类外重载-号
float real,imag;
};
Complex operator-(const Complex &c1,const Complex &c2){//重载函数
return Complex(c1.real-c2.real,c1.imag-c2.imag);
}
int main(){
Complex c1(5,4),c2(2,2),c3;
c3 = c1 - c2; //使用运算符-号
c3.display();
return 0;
}
运行结果如下:
++运算符的前后重载
#include<iostream>
using namespace std;
class Complex{
public:
Complex(float a=0,float b=0):real(a),imag(b){};
void display(){
cout<<real<<"+"<<imag<<"i"<<endl;
}
Complex &operator ++();//++的前置运算符重载
Complex operator ++(int);//++的后置重载,需要用int参数来区分
private:
float real,imag;
};
Complex &Complex::operator ++()//前置
{
real++;
imag++;
return (*this);
}
Complex Complex::operator ++(int){//后置,返回一个对象
return Complex(real++,imag++);
}
int main(){
Complex c1(5,4),c2(2,2),c3,c4;
c3 = c1--;//前置运算
c4 = --c2;//后置运算
c1.display();
c2.display();
c3.display();
c4.display();
return 0;
}
运行结果如下:
虚函数
- virtual类型的函数
virtual 函数类型 函数名(){
函数体
}
举个例子:
#include<iostream>
using namespace std;
class Base1{
public:
virtual void display()const;//虚函数
};
void Base1::display()const{
cout<<"Base1::display()"<<endl;
}
class Base2:public Base1{
public:
virtual void display()const;
};
void Base2::display()const{
cout<<"Base2::display()"<<endl;
}
class Derived:public Base2{
public:
virtual void display()const;
};
void Derived::display()const{
cout<<"Derived::display()"<<endl;
}
void fun(Base1 *p){
p->display();
}
int main(){
Base1 base1;
Base2 base2;
Derived derived;
fun(&base1);
fun(&base2);
fun(&derived);
return 0;
}
定义一个基类Base1,派生Base2,最远派生Derive.他们都有一个display函数,现在要用fun函数传入一个指针参数,来全能的调用各个类的display函数。
结果如下:
那如果我们不用这个虚函数会怎么样呢?
我们把每个类中的display函数设为非虚函数运行之后:
可以看到,如果没有虚函数的话,那么程序将会进行静态绑定,fun函数中用的是Base1的指针,那么不管传进去的是什么指针,都会调用Base1的display函数。
抽象类
纯虚函数:
纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的版本
纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的版本,纯虚函数的声明格式为:
virtual 函数类型 函数名(参数表) = 0 ;//等于0表示没有函数体
只要有一个纯虚函数,这个类就是抽象类。
抽象类只能作为基类来使用,不能定义抽象类的对象(但还是可以有相应的指针)