利用虚函数实现动态绑定
多态主要体现在虚函数上,只要有虚函数存在,对象类型就会在程序运行时动态绑定。动态绑定的实现方法是定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象,通过该指针变量调用此虚函数。
例子:
#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类的构造函数构造对象。
结果:
从结果中可以看出,“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;
}
结果:
上述代码在定义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
请登录后发表评论
注册