虚函数特性--复习一

作者在 2008-08-31 17:24:17 发布以下内容

虚函数是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()

基础知识 | 阅读 3492 次
文章评论,共0条
游客请输入验证码
浏览1944746次