重载和多态

重载与多态

多态的概念

多态是指同样的消息被不同类型的对象接收时导致不同的行为,所谓的消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数。

运算符的重载

运算符在类内的重载:

#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();//展示出来
}

运行结果如下
Kw5fWq.png

运算符在类外的重载

#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;
}

运行结果如下:
Kw7C0U.png

++运算符的前后重载

#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;
} 

运行结果如下:
KwbCi4.png

虚函数

  • virtual类型的函数

virtual 函数类型 函数名(){
函数体
}
Ka3mMd.png
举个例子:

#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函数。
结果如下:
KwOx1J.png
那如果我们不用这个虚函数会怎么样呢?
我们把每个类中的display函数设为非虚函数运行之后:
KwjgJS.png
可以看到,如果没有虚函数的话,那么程序将会进行静态绑定,fun函数中用的是Base1的指针,那么不管传进去的是什么指针,都会调用Base1的display函数。

抽象类

纯虚函数:
纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的版本
纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的版本,纯虚函数的声明格式为:
virtual 函数类型 函数名(参数表) = 0 ;//等于0表示没有函数体
只要有一个纯虚函数,这个类就是抽象类。
抽象类只能作为基类来使用,不能定义抽象类的对象(但还是可以有相应的指针)

posted @ 2019-10-25 23:16  醉死的乌鸦  阅读(199)  评论(0编辑  收藏  举报