虚函数

来源:互联网 发布:山东省教师网络研修 编辑:程序博客网 时间:2024/05/21 04:20

 一、虚函数

基本概念 首先,C++通过虚函数实现多态."无论发送消息的对象属于什么类,它们均发送具有同一形式的消息,对消息的处理方式可能随接手消息的对象而变"的处理方式被称为多态性。"在某个基类上建立起来的类的层次构造中,可以对任何一个派生类的对象中的同名过程进行调用,而被调用的过程提供的处理可以随其所属的类而变。"虚函数首先是一种成员函数,它可以在该类的派生类中被重新定义并被赋予另外一种处理功能。


1.基类的某函数是虚函数,那么子类的相同函数是虚函数么?
是的。虚函数有传递性,基类的函数是虚的,那么子类的相同函数也是虚的,不管子类的这个函数的定义前有没有加上virtual关键字。
虚函数的传递性只能从基类向子类传递。如果基类中的某个函数非虚,而他的子类把这个函数设成虚函数,这时通过基类的指针调用这个函数,调用的基类的版本。多态有两个条件,一是通过基类的指针调用,二是调用的函数是基类的虚函数。上面这个情况不满足条件二。

2.析构函数在什么情况下应该写成虚函数?
如果一个类可能被其他类继承,那么这个类析构函数应该成为虚函数。否则,通过基类的指针析构时只会析构基类的部分!
class Base

{
public:
    ~Base() { cout << "in base's destructor" <<endl; }
};
class Derived

{
public:
    ~Derived() { cout << "in derived's destructor" <<endl;}
}
Base *pb; //很多情况都是通过基类指针来操作各个继承类
pb = new Derived;
……
delete pb; //!只有基类的部分被析构
如果把基类的析构函数设成虚函数,那么通过基类指针调用时就会调用正确的析构函数。把基类的析构函数设置成虚函数,那么在编译时,编译器知道应该到运行时再决定要调用的析构函数的版本,在运行时就根据指针指向的类型选择相应的类的析构函数。
子类的析构函数隐含着对基类的析构函数的调用。类似于:
~Derived()

{
      ……                        //这个类的析构函数做的工作
      Base::~Base();        //编译器帮你加的
}

3.虚函数和函数重载
C++中标识一个函数是通过函数名和参数,所以同名函数的重载版本实际上是不同的函数。把这些重载函数的其中一个设成虚函数,并不影响它的重载函数的性质。
顺便提一下,重载和继承(参考《C++ Primer》):
子类如果定义(或者重新定义)基类的函数的重载版本,那么基类的这个函数的所有重载版本,除了在子类中定义的那些,对于子类的对象而言都不可见了。
如果要使用基类中定义的某函数的重载版本,需要在子类中原封不动的定义一下。比如:
Derived::func(double var) { Base::func(var); }
另一种解决方法:使用using声明。using的一般使用格式:using 基类::函数名;。因为这个格式中不带参数,使用它相当于在子类引进了基类的某个函数的所用重载版本。比如:
class Derived:public Base

{
public:
    using Base::func; //引进了所用重载版本
    void func(double);//重新定义一下func函数的double版本
}

原创粉丝点击