8.7 程序举例

 

8.7 程序举例

本节通过两个例子展示了多态性和虚函数的实际应用。

例8.18 计算几种几何图形的面积之和

这个例子计算了五种几何图形(矩形、三角形、圆形、梯形、正方形)的面积之和。以下是程序的实现:

#include <iostream>
using namespace std;

class Shape {
public:
    virtual double Area() const = 0;
};

class Triangle : public Shape {
public:
    Triangle(double h, double w) : H(h), W(w) {}
    double Area() const override {
        return H * W * 0.5;
    }

private:
    double H, W;
};

class Rectangle : public Shape {
public:
    Rectangle(double h, double w) : H(h), W(w) {}
    double Area() const override {
        return H * W;
    }

private:
    double H, W;
};

class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    double Area() const override {
        return radius * radius * 3.1415;
    }

private:
    double radius;
};

class Trapezoid : public Shape {
public:
    Trapezoid(double top, double bottom, double high)
        : T(top), B(bottom), H(high) {}
    double Area() const override {
        return (T + B) * H * 0.5;
    }

private:
    double T, B, H;
};

class Square : public Shape {
public:
    Square(double side) : S(side) {}
    double Area() const override {
        return S * S;
    }

private:
    double S;
};

class Application {
public:
    double Compute(Shape* s[], int n) const {
        double sum = 0;
        for (int i = 0; i < n; ++i)
            sum += s[i]->Area();
        return sum;
    }
};

class MyProgram : public Application {
public:
    MyProgram() {
        s = new Shape*[5];
        s[0] = new Triangle(3.0, 4.0);
        s[1] = new Rectangle(6.0, 8.0);
        s[2] = new Circle(6.5);
        s[3] = new Trapezoid(10.0, 8.0, 5.0);
        s[4] = new Square(6.7);
    }
    ~MyProgram() {
        for (int i = 0; i < 5; ++i)
            delete s[i];
        delete[] s;
    }
    double Run() {
        return Compute(s, 5);
    }

private:
    Shape** s;
};

int main() {
    cout << "Area's sum = " << MyProgram().Run() << endl;
    return 0;
}
说明
  • 抽象类 Shape:定义了一个纯虚函数 Area,作为所有几何图形的基类。
  • 五个派生类TriangleRectangleCircleTrapezoidSquare,每个类都实现了 Area 函数。
  • Application 类:包含一个计算面积和的函数 Compute
  • MyProgram 类:继承自 Application,在构造函数中创建了五个几何图形对象,在析构函数中删除这些对象。

程序的输出结果为:

 

mathematica

复制代码

Area's sum = 276.618

这种结构使得添加新图形非常方便,只需增加一个继承自 Shape 的派生类并实现 Area 函数即可。

例8.19 宠物管理系统

该例子展示了一个宠物管理系统,假设一个人拥有20个宠物窝,一半用于养猫,另一半用于养狗。程序定义了一个动物基类 Animal,以及 CatDog 两个派生类,并实现了虚函数 WhoAmI

#include <iostream>
#include <cstring>
using namespace std;

class Animal {
public:
    Animal() : name(nullptr) {}
    Animal(const char* n) : name(strdup(n)) {}
    virtual ~Animal() { delete[] name; }
    virtual void WhoAmI() { cout << "generic animal." << endl; }

protected:
    char* name;
};

class Cat : public Animal {
public:
    Cat() : Animal() {}
    Cat(const char* n) : Animal(n) {}
    void WhoAmI() override {
        cout << "I am a cat named " << name << endl;
    }
};

class Dog : public Animal {
public:
    Dog() : Animal() {}
    Dog(const char* n) : Animal(n) {}
    void WhoAmI() override {
        cout << "I am a dog named " << name << endl;
    }
};

class Kennel {
public:
    Kennel(unsigned max);
    ~Kennel();
    unsigned Accept(Animal* d);
    Animal* Release(unsigned pen);
    void ListAnimals();

private:
    unsigned MaxAnimals, NumAnimals;
    Animal** Residents;
};

Kennel::Kennel(unsigned max) : MaxAnimals(max), NumAnimals(0) {
    Residents = new Animal*[MaxAnimals];
    for (unsigned i = 0; i < MaxAnimals; ++i)
        Residents[i] = nullptr;
}

Kennel::~Kennel() {
    for (unsigned i = 0; i < MaxAnimals; ++i)
        delete Residents[i];
    delete[] Residents;
}

unsigned Kennel::Accept(Animal* d) {
    if (NumAnimals == MaxAnimals)
        return 0;
    for (unsigned i = 0; i < MaxAnimals; ++i) {
        if (Residents[i] == nullptr) {
            Residents[i] = d;
            ++NumAnimals;
            return i + 1;
        }
    }
    return 0;
}

Animal* Kennel::Release(unsigned pen) {
    if (pen > MaxAnimals || Residents[pen - 1] == nullptr)
        return nullptr;
    Animal* temp = Residents[pen - 1];
    Residents[pen - 1] = nullptr;
    --NumAnimals;
    return temp;
}

void Kennel::ListAnimals() {
    for (unsigned i = 0; i < MaxAnimals; ++i) {
        if (Residents[i] != nullptr) {
            cout << "The animal in pen " << i + 1 << " says:" << endl;
            Residents[i]->WhoAmI();
        }
    }
}

Dog d1("Rover"), d2("Spot"), d3("Chip"), d4("Buddy"), d5("Butch");
Cat c1("Tinkerbell"), c2("Inky"), c3("Fluffy"), c4("Princess"), c5("Sylvester");

int main() {
    Kennel K(20);
    K.Accept(&d1);
    unsigned c2pen = K.Accept(&c2);
    K.Accept(&d3);
    K.Accept(&c1);
    unsigned d4pen = K.Accept(&d4);
    K.Accept(&d5);
    K.Accept(&c5);
    K.Release(c2pen);
    K.Accept(&c4);
    K.Accept(&c3);
    K.Release(d4pen);
    K.Accept(&d2);
    K.ListAnimals();
    return 0;
}
说明
  • 基类 Animal:定义了虚函数 WhoAmI,用于输出动物的身份信息。
  • 派生类 Cat 和 Dog:分别实现了 WhoAmI 函数,输出各自的身份信息。
  • Kennel 类:管理动物的数组,提供接收、释放和列出动物的方法。

程序的输出结果如下:

The animal in pen 1 says: I am a dog named Rover
The animal in pen 2 says: I am a cat named Princess
The animal in pen 3 says: I am a dog named Chip
The animal in pen 4 says: I am a cat named Tinkerbell
The animal in pen 5 says: I am a dog named Spot
The animal in pen 6 says: I am a dog named Butch
The animal in pen 7 says: I am a cat named Sylvester
The animal in pen 8 says: I am a cat named Fluffy

这个例子展示了虚函数的使用,使得对不同类型的动物有统一的操作接口,方便地进行多态操作。

结论

通过以上两个例子,我们可以看到虚函数和多态性在实际编程中的重要应用。虚函数使得程序能够根据对象的实际类型调用相应的方法,从而实现了多态性。这种机制极大地提高了程序的灵活性和可扩展性,便于维护和扩展功能。希望本文对虚函数和多态性的理解有所帮助,为编写更灵活、更易维护的C++程序提供支持。

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值