虚函数是C++中实现多态的机制。下面通过几个小程序实验来复习一下虚函数的概念用法。
#include
class A
{
public:
virtual void f() { cout
<< "A::f()" << endl; }
};
class B : public A
{
public:
void f() { cout
<< "B::f()" << endl; }
};
int main()
{
A *a = new
B;
a->f();
return 0;
}
在这个实验中a虽然是指向A,但调用的f()却是B的。
在基类中声明的虚函数在派生类中也是虚的,即使没有加上virtual关键字,例如:
#include
class A
{
public:
virtual void f() { cout
<< "A::f()" << endl; }
};
class B : public A
{
public:
void f() { cout
<< "B::f()" << endl; } //未加virtual关键字,实际上也是虚的
};
class C: public B
{
public:
void f() { cout
<< "C::f()" << endl; } //未加virtual关键字,实际上也是虚的
};
int main()
{
A *a = new B;
a->f(); //调用的是B的f()
A *a1 = new C;
a1->f(); //调用的是C的f()
B *b = new C;
b->f(); //这里调用的也是C的f(),说明B的f()也是虚的
return
0;
}
基类的析构函数必须是虚的,例如:
#include
class A
{
public:
A() { p = new char[10]; cout
<< "A()" << endl; }
~A() { delete [] p; cout << "~A"
<< endl; }
private:
char *p;
};
class B : public A
{
public:
B() { p1 = new
char[20]; cout << "B()" << endl; }
~B() { delete [] p1; cout
<< "~B" << endl; }
private:
char *p1;
};
int main()
{
A *a = new B;
delete
a;
return 0;
}
运行结果:
A()
B()
~A()
也就是说B的析构函数并未被调用,这是多么严重的事情啊!看看加了virtual之后的情况:
#include
class A
{
public:
A() { p = new char[10]; cout
<< "A()" << endl; }
virtual ~A() { delete [] p; cout <<
"~A" << endl; }
private:
char *p;
};
class B : public A
{
public:
B() { p1 = new
char[20]; cout << "B()" << endl; }
~B() { delete [] p1; cout
<< "~B" << endl; }
private:
char *p1;
};
int main()
{
A *a = new B;
delete
a;
return 0;
}
运行结果:
A()
B()
~B()
~A()
好的B的析构被调用了,还要注意类被构造析构的是进栈出栈的顺序。
再看一下纯虚函数。纯虚函数只是提供了一个接口罢了,她告诉使用者我的派生类中都会有这个函数。
#include
class A
{
public:
virtual void f1() =
0;
virtual void f2() { cout << "A::f2()" << endl;
}
};
class B : public A
{
public:
void f1() { cout
<< "B::f1" << endl; }
void f2() { cout << "B::f2()"
<< endl; }
};
int main()
{
A *a = new
B;
a->f1();
a->f2();
return 0;
}
运行结果:
B::f1
B::f2()