C++——虚函数与多态性

定义

  1. 多态性是指一个名字,多种语义,重载函数是多态性的一种简单形式
  2. 虚函数为向类提供的一种灵活的多态机制,允许函数调用与函数体在运行时才进行联系,成为动态联编

联编类型

类型说明
静态联编指程序之间的匹配、连接在编译阶段,即程序运行之前完成,也称早期匹配
动态联编指程序联编推迟带运行时进行,又称为晚期联编;switch语句就是一个例子

类指针的关系

方式权限
直接用基类指针引用基类对象安全
直接用派生类指针引用派生类对象安全
用基类指针引用派生类对象安全
用派生类指针引用基类对象强制转换

基类指针引用派生类对象

class A_class{
		char name[20];
	public:
		void put_name(char *s)
		{	strcpy_s(name,s);	}
		void show_name()const
		{	cout<<name<<"\n";	}
};
class B_class:public A_class{
		char phone_num[20];
	public:
	void put_phone(char *num)
	{	strcpy_s(phone_num,num);	}
	void show_phone()const
	{	cout<<phone_num<<"\n";	}
};
int main(){
	A_class *A_pl
	A_class A_obj;
	B_class B_obj;
	A_p=&A_obj;
	A_p->put_name("wang xiao hua");
	A_p->show_name();
	A_p=&B_obj;//基类指针指向派生类对象
	A_p->put_name("chen ming");
	A_p->show_name();
	B_obj.put_phone("5555_12345678");
	((B_class*)A_p)->show_phone();//对基类指针进行强制类型转换
}

派生类指针引用基类对象

class Date{
	public:
		Date(int y,int m,int d)
		{	SetDate(y,m,d);	 }
		void SetDate(int y,int m,int d)
		{	year=y; month=m; day=d;	}
		void Print()const
		{	cout<<year<<month<<day;		}
	protected:
		int year,month,day;
};

class DateTime:public Date{
	public:
		DateTime(int y,int m,int d,int h,int mi,int s):Date(y,m,d)
		{	SetDateTime(h,mi,s)};
		void SetTime(int h,int mi,int s){
		hours=h;
		minutes=mi;
		seconds=s;
		}
		void Print()const
		{	cout<<hours<<minutes<<seconds<<endl;	}
	privateint hours,minutes,seconds;
};

int main(){
	DateTime dt(2003,1,1,12,30,0);
	DateTIme *pdt=&dt;
	((Date).dt).Print();//对象类型转换,调用基类成员函数
	dt.Print();
	((Date *)pdt)->Print();//对象指针类型转换,调用基类成员函数
	pdt->Print();
}

虚函数与动态联编

  1. 基类设计为虚函数,随着基类指针指向不同的派生类调用不同版本的虚函数
  2. 虚函数的重载特性:要求函数名,返回类型,参数个数,类型和顺序完全相同;
class Base{
	public:
		Base(char xx)
		{	x=xx;	}
		virtual void who()//说明虚函数
		{	cout<<x<<endl;	}
	protected:
		char x;
};

class First_d:public Base{
	public:
		First_d(char xx,char yy):Base(xx){y=yy;}
		void who()//默认说明虚函数
		{	cout<<x<<y<<endl;	}
	protected:
		char y;
};

class Second_d:public First_d{
	public:
		Second_d(char xx,char yy,char zz):First_d(xx,yy)
		{	z=zz;	}
		void who()//默认说明虚函数
		{	cout<<x<<y<<z<<endl;	}
	protected:
		char z;
};

int main(){
	Base B_obj('A');
	Base *p;
	First_d F_obj('T','O');
	Second_d S_obj('E','N','D');
	//随着基类指针指向不同的派生类,调用不同版本的虚函数
	p=&B_obj;
	p->who();
	p=&F_obj;
	p->who();
	p=&S_obj;
	p->who();
}

虚析构函数

  1. 构造函数不能是虚函数,因为构造派生类必须从底层依次构建,不存在版本问题;
  2. 虚析构函数用于动态建立类对象时,指引delete运算符选择正确的析构调用;
  3. 基类的析构函数说明为虚函数没有坏处;
class A{
	public:
		~A();
		{	cout<<"~A() is called";		}
};

class B:public class A{
	public:
		~B()
		{	cout<<"~B() is called";		}
};

int main(){
	A *Ap=new B:
	B *Bp2=new B;
	delete Ap;//只调用~A() 资源无法完成释放
	Ap=NULL;
	delete Bp2;
	Bp2=NULL;
}
class A{
	public:
		virtual ~A();
		{	cout<<"~A() is called";		}
};

class B:public class A{
	public:
		~B()
		{	cout<<"~B() is called";		}
};

int main(){
	A *Ap=new B:
	B *Bp2=new B;
	delete Ap;//调用~A() 和 ~B()
	Ap=NULL;
	delete Bp2;
	Bp2=NULL;
}

纯虚函数与抽象类

  1. 虚函数为基类仅说明一个公共的界面,而由各派生类提供各自的实现版本,虚函数没有定义,只有声明
  2. 一个具有纯虚函数的基类称为抽象类,抽象类至少有一个纯虚函数;

对抽象类的使用限制:

  1. 抽象类只能用作其他类的基类
  2. 抽象类不能建立对象
  3. 抽象类不能用作参数类型,参数返回类型或显示类型转换
  4. 只能用于申明抽象指针,抽象运用
  5. 如果抽象类的派生类不提供纯虚函数的实现,他依然是抽象类
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值