C++的多态实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/88623610

一 指向基类指针的例子

1 代码

#include <iostream>
using namespace std;
class CPolygon {
protected:
    int width, height;
public:
    void set_values(int a, int b) {
        width = a; height = b;
    }
};
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;
    // ppoly1和ppoly2被赋值为rect和trgl的地址,因为rect和trgl是CPolygon的子类对象,因此这种赋值是有效的。
    CPolygon * ppoly1 = &rect;
    CPolygon * ppoly2 = &trgl;
    ppoly1->set_values(4, 5);
    ppoly2->set_values(4, 5);
    cout << rect.area() << endl;
    cout << trgl.area() << endl;
    return 0;
}

2 运行

[root@localhost test]# g++ test.cpp -g -o test
[root@localhost test]# ./test
20
10

3 说明

继承的好处之一是一个指向子类的指针与一个指向基类的指针是类型兼容的。

使用*ppoly1和*ppoly2取代rect和trgl的唯一限制是*ppoly1和*ppoly2是CPolygon*类型的,因此只能够引用CRectangle和CTriangle中继承的成员。正是由于这个原因,我们不能够使用*ppoly1和*ppoly2来调用成员函数area(),而只能使用rect和trgl来调用这个函数。

二 虚拟成员

1 代码

#include <iostream>
using namespace std;
class CPolygon {
protected:
    int width, height;
public:
    void set_values(int a, int b) {
        width = a;
        height = b;
    }
    // 如果想在基类中定义成员留给子类进行细化,我们必须在它前面加关键字virtual,以便可以使用指针对指向相应的对象进行操作
    virtual int area(void) { return (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 poly;
    CPolygon * ppoly1 = &rect;
    CPolygon * ppoly2 = &trgl;
    CPolygon * ppoly3 = &poly;
    ppoly1->set_values(4, 5);
    ppoly2->set_values(4, 5);
    ppoly3->set_values(4, 5);
    cout << ppoly1->area() << endl;
    cout << ppoly2->area() << endl;
    cout << ppoly3->area() << endl;
    return 0;
}

2 运行

[root@localhost test]# g++ test.cpp -g -o test
[root@localhost test]# ./test
20
10
0

3 说明

关键字virtual的作用就是在使用基本的指针的时候,使子类中与基类同名的成员在适当的时候被调用。

注意:虽然本身被定义为虚拟类型,我们还是可以声明一个CPolygon类型的对象并调用它的area()函数,它将返回0.

三 第一个抽象基类的例子

1 代码

#include <iostream>
using namespace std;
class CPolygon {
protected:
    int width, height;
public:
    void set_values(int a, int b) {
        width = a;
        height = b;
    }
    // 该函数是纯虚拟函数,包含纯虚拟函数的类被称为抽象基类
    virtual int area(void) = 0;   // 简单地在函数声明后面写“= 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;
}

2 运行

[root@localhost test]# g++ test.cpp -g -o test
[root@localhost test]# ./test
20
10

3 说明

抽象基类的最大不同是它不能够有实例,但我们可以定义指向它的指针。

四 第二个抽象基本的例子

1 代码

#include <iostream>
using namespace std;
class CPolygon {
protected:
    int width, height;
public:
    void set_values(int a, int b) {
        width = a;
        height = b;
    }
    virtual int area(void) = 0;
    void printarea(void) {
        cout << this->area() << endl; // this代表正在被执行的这个对象的指针
    }
};
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);
    ppoly1->printarea();
    ppoly2->printarea();
    return 0;
}

2 运行

[root@localhost test]# g++ test.cpp -g -o test
[root@localhost test]# ./test
20
10

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/88623610