虚函数:
在某
基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。
我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。
定义虚函数的限制
:
(1)非类的成员函数不能定义为虚函数,类的成员函数中静态成员函数和构造函数也不能定义为虚函数,但可以将析构函数定义为虚函数。实际上,优秀的程序员常常把基类的析构函数定义为虚函数。因为,将基类的析构函数定义为虚函数后,当利用delete删除一个指向派生类定义的对象指针时,系统会调用相应的类的析构函数。而不将析构函数定义为虚函数时,只调用基类的析构函数。
(2)只需要在声明函数的类体中使用关键字“virtual”将函数声明为虚函数,而定义函数时不需要使用关键字“virtual”。
(3)当将基类中的某一成员函数声明为虚函数后,派生类中的同名函数(函数名相同、参数列表完全一致、返回值类型相关)自动成为虚函数。
(4)如果声明了某个成员函数为虚函数,则在该类中不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。在以该类为基类的派生类中,也不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。虚函数联系到多态,多态联系到继承。
#include<iostream>
using namespace std;
class A
{
public:
virtual void fn1(){cout<<"A:fn1"<<endl;}
virtual void fn2(){cout<<"A:fn2"<<endl;}
virtual void fn3(){cout<<"A:fn3"<<endl;}
void fn(){cout<<"fn"<<endl;}
};
class B:public A
{
public:
virtual void fn1(){cout<<"B:fn1"<<endl;}
virtual void fn4(){cout<<"B:fn4"<<endl;}
virtual void fn5(){cout<<"B:fn5"<<endl;}
void fnn(){cout<<"fnn"<<endl;}
};
class C:public A
{
public:
virtual void fn1(){cout<<"C:fn1"<<endl;}
virtual void fn2(){cout<<"C:fn2"<<endl;}
virtual void fn6(){cout<<"C:fn6"<<endl;}
virtual void fn7(){cout<<"C:fn7"<<endl;}
void fnnn(){cout<<"fnnn"<<endl;}
};
void test(A &a)
{
a.fn1();
a.fn2();
a.fn3();
}
void fun(B &b)
{
b.fn1();
b.fn4();
b.fn5();
}
void main()
{
A a;
B b;
C c;
test(a);
test(b);
test(c);
fun(b);
cout<<(int*)&a<<endl;
cout<<(int*)*((int*)&a)<<endl;
cout<<(int*)&b<<endl;
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}