c++之虚函数

引例:
class Animail{
public:
void Function_1() {cout <<"Animail::Function_1()"<<endl;};
};

classDog: public Animail{
public:
void Function_1() {cout <<"Dog::Function_1()"<<endl;};
};
int main(int argc, char* argv[])
{
Animail*p = NULL; //定义基类的指针
Animail cAnimail;
Dog cDog;

p = &cAnimail;
p->Function_1();

p =&cDog;
p->Function_1();
return 0;
}

这段代码的输出结果是什么呢?起初认为是:Animail::Function_1()与Dog::Function_1(),因为第一次输出是引用基类Animail的实例,第二次输出是引用子类Dog的实例。事实上答案是Animail::Function_1()与 Animail::Function_1(),为什么呢?

这里我们需要明白:你就记住,不管引用的实例是哪个类的,当你调用的时候,系统会调用左值那个对象所属类的方法。比如说上面的代码类Animail和 Dog都有一个Function_1函数,因为p是一个Animail类的指针,所以不管你将p指针指向类Animail或是类Dog,最终调用的函数都是类Animail的Function_1函数。这就是静态联篇,编译器在编译的时候就已经确定好了。可是如果我想实现跟据实例的不同来动态决定调用哪个函数呢?这就须要用到虚函数(也就是动态联篇)。

class Animail{
public:
virtual void Function_1() {cout <<"Animail::Function_1()"<<endl;};
};

class Dog: public Animail{
public:
virtual void Function_1() {cout <<"Dog::Function_1()"<<endl;};
};

所谓虚函数就是在编译的时候不确定要调用哪个函数,而是动态决定将要调用哪个函数。它的作用就是为了能让这个函数在它的子类里面可以被重载,这样的话,编译器就可以使用后期绑定来达到多态了,也就是:用基类的指针来调用子类的这个函数。

虚函数是一种特殊的虚函数,它的一般格式如下:

class <类名>
{
virtual <类型><函数名>(<参数表>)=0;
};

基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

引入原因:

1、为了方便使用多态特性,我们常常需要在基类中定义虚函数。

2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;)。若要使派生类为非抽象类,则编译器要求在派生类中,必须对纯虚函数予以重写以实现多态性。同时含有纯虚函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。


你可能感兴趣的:(C++,虚函数)