C++——多态之虚函数与虚继承 – 作者:Johnson666

利用虚函数实现动态绑定

多态主要体现在虚函数上,只要有虚函数存在,对象类型就会在程序运行时动态绑定。动态绑定的实现方法是定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象,通过该指针变量调用此虚函数。

例子:

#include<iostream>
using namespace std;

class Employee
{
public:
	int id;
	char name[128];
	char depart[128];
	Employee()
	{
		memset(name,0,128);
		memset(depart,0,128);
	}
	virtual void outputName()  //定义一个虚成员函数
	{
		cout << "Employee's name:" << name << endl;
	}
};

class Operator:public Employee  //从Employee类派生一个子类
{
public:
	char password[128];
	void outputName()  //定义outputName虚函数
	{
		cout << "Operator's name:" << name << endl;
	}
};

int main()
{
	Employee *pWorker = new Operator();  //定义Employee类型指针,调用Operator类构造函数
	strcpy(pWorker->name,"Johnson666");  //设置name数据成员信息
	pWorker->outputName();
	delete pWorker;
	return 0;
}

上述代码中,在Employee类中定义了一个虚函数outputName,在子类Operator中改写了outputName成员函数,其中Operator类中的outputName成员函数即使没有使用virtual关键字仍为虚函数。下面定义一个Employee类型的指针,调用Operator类的构造函数构造对象。

结果:
image.png
从结果中可以看出,“pWorker->outputName();”语句调用的是Operator类的outputName成员函数。虚函数有以下几方面限制。

(1)只有类的成员函数才能为虚函数。
(2)静态成员函数不能是虚函数,因为静态成员函数不受限于某个对象。
(3)内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的。
(4)构造函数不能是虚函数,析构函数通常是虚函数。

虚继承

如何在派生子类时使其只存在一个基类呢?C++语言提供了虚继承机制,解决了这个问题。

例子:

#include<iostream>
using namespace std;

class Animal
{
public:
	Animal()
	{
		cout << "动物类被构造" << endl;
	}
	void Move()
	{
		cout << "动物能够移动" << endl;
	}
};

class Bird:virtual public Animal  //从Animal类虚继承Bird类
{
public:
	Bird()
	{
		cout << "鸟类被构造" << endl;
	}
	void FlyInSky()
	{
		cout << "鸟能够在天空飞翔" << endl;
	}
	void Breath()
	{
		cout << "鸟能够呼吸" << endl;
	}
};

class Fish:virtual public Animal  //从Animal类虚继承Fish类
{
public:
	Fish()
	{
		cout << "鱼类被构造" << endl;
	}
	void SwimInwater()
	{
		cout << "鱼能够在水里游" << endl;
	}
	void Breath()
	{
		cout << "鱼能够呼吸" << endl;
	}
};

class WaterBird:public Bird,public Fish  //从Bird和Fish类派生子类WaterBird
{
public:
	WaterBird()
	{
		cout << "水鸟类被构造" << endl;
	}
	void Action()
	{
		cout << "水鸟既能飞又能游" << endl;
	}
};

int main()
{
	WaterBird waterbird;
	return 0;
}

结果:
image.png
上述代码在定义Bird类和Fish类时使用了关键字virtual从基类Animal派生而来。实际上,虚继承对于Bird类和Fish类没有多少影响,却对WaterBird类产生了很大的影响。WaterBird类中不再有两个Animal类的复制,而只存在一个Animal的复制。
通常,在定义一个对象时,先依次调用基类的构造函数,最后才调用自身的构造函数。但是对于虚继承来说,情况有些不同。在定义WaterBird类对象时,先调用基类Animal的构造函数,然后调用Bird类的构造函数,这里Bird类虽然为Animal的子类,但是在调用Bird类的构造函数时将不再调用Animal类的构造函数。对于Fish类也是同样的道理。
在程序开发过程中,多继承虽然带来了很多方便,但是很少有人愿意使用它,因为它会带来很多复杂的问题,并且它能够完成的功能通过单继承同样可以实现。因此,大家在开发应用程序时,如果能使用单继承实现,尽量不要使用多继承。

来源:freebuf.com 2021-06-14 16:58:15 by: Johnson666

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论