学学习网 手机版

学学习网

学习路径: 学习首页 > 应用开发 > c++ >

第六节 类(Classes)(12)

设置字体:
----------------------------------

area() 被定义为virtual 是因为它后来在子类中被细化了。你可以做一个试验,如果在代码种去掉这个关键字(virtual),然后再执行这个程序,三个多边形的面积计算结果都将是 0 而不是20,10,0。这是因为没有了关键字virtual ,程序执行不再根据实际对象的不用而调用相应area() 函数(即分别为CRectangle::area(), CTriangle::area() 和 CPolygon::area()),取而代之,程序将全部调用CPolygon::area(),因为这些调用是通过CPolygon类型的指针进行的。
因此,关键字virtual 的作用就是在当使用基类的指针的时候,使子类中与基类同名的成员在适当的时候被调用,如前面例子中所示。
注意,虽然本身被定义为虚拟类型,我们还是可以声明一个CPolygon 类型的对象并调用它的area() 函数,它将返回0 ,如前面例子结果所示。
 
抽象基类(Abstract base classes)
基本的抽象类与我们前面例子中的类CPolygon 非常相似,唯一的区别是在我们前面的例子中,我们已经为类CPolygon的对象(例如对象poly)定义了一个有效地area()函数,而在一个抽象类(abstract base class)中,我们可以对它不定义,而简单得在函数声明后面写 =0 (等于0)。
类CPolygon 可以写成这样:
// abstract class CPolygon
class CPolygon {
    protected:
        int width, height;
    public:
        void set_values (int a, int b) {
            width=a;
            height=b;
        }
        virtual int area (void) =0;
};
注意我们是如何在virtual int area (void)加 =0 来代替函数的具体实现的。这种函数被称为纯虚拟函数(pure virtual function),而所有包含纯虚拟函数的类被称为抽象基类(abstract base classes)。
抽象基类的最大不同是它不能够有实例(对象),但我们可以定义指向它的指针。因此,像这样的声明:
CPolygon poly;
对于前面定义的抽象基类是不合法的。
然而,指针:
CPolygon * ppoly1;
CPolygon * ppoly2
是完全合法的。这是因为该类包含的纯虚拟函数(pure virtual function) 是没有被实现的,而又不可能生成一个不包含它的所有成员定义的对象。然而,因为这个函数在其子类中被完整的定义了,所以生成一个指向其子类的对象的指针是完全合法的。
下面是完整的例子:
// virtual members
#include <iostream.h>
class CPolygon {
    protected:
        int width, height;
    public:
        void set_values (int a, int b) {
            width=a;
            height=b;
        }
        virtual int area (void) =0;
};
class CRectangle: public CPolygon {
    public:
        int area (void) { return (width * height); }
};
class CTriangle: public CPolygon {
    public:
        int area (void) {
            return (width * height / 2);
        }
};
int main () {
    CRectangle rect;
    CTriangle trgl;
    CPolygon * ppoly1 = &rect;
    CPolygon * ppoly2 = &trgl;
    ppoly1->set_values (4,5);
    ppoly2->set_values (4,5);
    cout << ppoly1->area() << endl;
    cout << ppoly2->area() << endl;
    return 0;
}
20
10
再看一遍这段程序,你会发现我们可以用同一种类型的指针(CPolygon*)指向不同类的对象,至一点非常有用。 想象一下,现在我们可以写一个CPolygon 的成员函数,使得它可以将函数area()的结果打印到屏幕上,而不必考虑具体是为哪一个子类。
----------------------------------
课程列表
重点难点
赞助链接