虚函数的注意事项:
-
只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加。
-
为了方便,你可以只将基类中的函数声明为虚函数,这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数。
-
当在基类中定义了虚函数时,如果派生类没有定义新的函数来遮蔽此函数,那么将使用基类的虚函数。
-
只有派生类的虚函数覆盖基类的虚函数(函数原型相同)才能构成多态(通过基类指针访问派生类函数)。
例如:基类虚函数的原型为virtual void func();
派生类虚函数的原型为virtual void func(int);
那么当基类指针 p 指向派生类对象时,
语句p -> func(100);将会出错,
而语句p -> func();将调用基类的函数。 -
构造函数不能是虚函数。对于基类的构造函数,它仅仅是在派生类构造函数中被调用,这种机制不同于继承。也就是说,派生类不继承基类的构造函数,将构造函数声明为虚函数没有什么意义。
-
析构函数可以声明为虚函数。
例子演示:
#include <iostream>
using namespace std;
//基类Base
class Base{
public:
virtual void func();
virtual void func(int);
};
void Base::func(){
cout<<"void Base::func()"<<endl;
}
void Base::func(int n){
cout<<"void Base::func(int)"<<endl;
}
//派生类Derived
class Derived: public Base{
public:
void func();
void func(char *);
};
void Derived::func(){
cout<<"void Derived::func()"<<endl;
}
void Derived::func(char *str){
cout<<"void Derived::func(char *)"<<endl;
}
int main(){
Base *p = new Derived();
p -> func(); //输出void Derived::func()
p -> func(10); //输出void Base::func(int)
p -> func("http://c.biancheng.net"); //compile error
return 0;
}
虚析构函数:
作用:虚析构函数是为了避免内存泄露,而且是当子类中会有指针成员变量时才会使用得到的。
也就说虚析构函数使得在删除指向子类对象的基类指针时可以调用子类的析构函数达到释放子类中堆内存的目的,而防止内存泄露的.
举例说明:
#include<iostream>
using namespace std;
class ClxBase
{
public:
ClxBase() {};
virtual ~ClxBase() { cout<<"delete ClxBase"<<endl; };
virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};
class ClxDerived : public ClxBase
{
public:
ClxDerived() {};
~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };
void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
int main(int argc, char const* argv[])
{
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
return 0;
}