一.简介
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次:
class Father
{
public:
virtual void foo() { cout << "Father::foo() is called"
<< endl;}
};
class Sun: public Father
{
public:
virtual void foo() { cout << "Sun::foo() is called" <<
endl;}
};
那么,在使用的时候,我们可以:
Father * a = new Sun(); //Father * a = new Father();
如果是这样的被调用的函数(foo)就是Father的
a->foo(); // 在这里,a虽然是指向Father的指针,但是被调用的函数(foo)却是Sun的!
这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并
不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。
虚函数只能借助于指针或者引用来达到多态的效果,如果是下面这样的代码,则虽然是虚函数,但它不是多态的:
class Father
{
public:
virtual void foo();
};
class Sun: public Father
{
virtual void foo();
};
void bar()
{
Father a;
a.foo(); // Father::foo()被调用
}
1.1 多态
在了解了虚函数的意思之后,再考虑什么是多态就很容易了。仍然针对上面的类层次,但是使用的方法变的复杂了一些:
void bar(Father * a)
{
a->foo(); // 被调用的是Father::foo() 还是Sun::foo()?只有当程序中对象 a
被初始化时才知道,如果
}
因为foo()是个虚函数,所以在bar这个函数中,只根据这段代码,无从确定这里被调用的是Father::foo()还是Sun::foo(),
但是可以肯定的说:如果a指向的是Father类的实例,则Father::foo()被调用,如果a指向的是Sun类的实例,则Sun::foo()被
调用。
这种同一代码可以产生不同效果的特点,被称为“多态”。
1.2 多态有什么用?
多态这么神奇,但是能用来做什么呢?这个命题我难以用一两句话概括,一般的C++教程(或者其它面向对象语言的教程)都用一个画图的例子来展示多态的
用途,我就不再重复这个例子了,如果你不知道这个例子,随便找本书应该都有介绍。我试图从一个抽象的角度描述一下,回头再结合那个画图的例子,也许你就更