# 上机四 运行时的多态性和抽象类程序设计

## 上机目的

1.理解多态性的概念。

2.掌握运行时的多态性概念和设计方法。

3.掌握虚函数的使用方法。

P187：6.10,6.11

## 上机内容(p187 6.11)

（1） 这三个类有一个公共的基类；

（2） 这三个类计算正方体、圆柱体、球体的表面积和体积的成员函数名字相同；

（3） 按照运行时的多态性方法设计一个测试主函数，并进行测试。

#include<iostream>
using namespace std;
class basic {
public:
virtual double superficial_area() = 0;
virtual double volume() = 0;
~basic()
{}
};
class cube :public basic
{
private:
double length;
public:
cube(double a):length(a)
{}
double superficial_area()
{
return(6 * length * length);
}
double volume()
{
return(length * length * length);
}
~cube()
{}
};
class cylinder :public basic
{
private:
double high;
public:
{}
double superficial_area()
{
}
double volume()
{
}
~cylinder()
{}
};
class globe :public basic
{
private:
public:
{}
double superficial_area()
{
}
double volume()
{
}
~globe()
{}
};
int main() {
int a;
char c, e, f;
double b, d, g, h;
basic* p;
cout << "请选择形状：" << endl;
cout << "1.正方形" << endl << "2.圆柱体" << endl << "3.球体" << endl;
cout << "-----------------------------------" << endl;
while (scanf("%d", &a) != EOF) {
switch (a) {
case 1:
{
cout << "请输入边长:";
cin >> b;
cube cube1(b);
p = &cube1;
cout << "-----------------------------------" << endl;
cout << "请选择操作：" << endl << "a.表面积" << endl << "b.体积" << endl << "c.返回" << endl;
while (cin >> c) {
if (c == 'a') {
cout << "正方体的表面积是：" << p->superficial_area() << endl;
}
if (c == 'b') {
cout << "正方体的体积是：" << p->volume() << endl;
}
if (c == 'c') {
cout << "-----------------------------------" << endl;
break;
}
}
break;
}
case 2:
{
cout << "请输入半径:";
cin >> d;
cout << endl;
cout << "请输入高：";
cin >> h;
cylinder cylinder1(d, h);
p = &cylinder1;
cout << "-----------------------------------" << endl;
cout << "请选择操作：" << endl << "a.表面积" << endl << "b.体积" << endl << "c.返回" << endl;
while (cin >> e) {
if (e == 'a') {
cout << "圆柱体的表面积是：" << p->superficial_area() << endl;
}
if (e == 'b') {
cout << "圆柱体的体积是：" << p->volume() << endl;
}
if (e == 'c') {
cout << "-----------------------------------" << endl;
break;
}
}
break;
}
case 3:
{
cout << "请输入半径:";
cin >> g;
globe globe1(g);
p = &globe1;
cout << "-----------------------------------" << endl;
cout << endl;
cout << "请选择操作：" << endl << "a.表面积" << endl << "b.体积" << endl << "c.返回" << endl;
while (cin >> f) {
if (f == 'a') {
cout << "球体的表面积是：" << p->superficial_area() << endl;
}
if (f == 'b') {
cout << "球体的体积是：" << p->volume() << endl;
}
if (f == 'c') {
cout << "-----------------------------------" << endl;
break;
}
}
break;
}
}
}
return 0;
}

以下是一个示例实现，满足上述所有要求：
#include <iostream>
#include <cmath>
using namespace std;
// 定义基类Shape
class Shape {
public:
// 虚析构函数
virtual ~Shape() {}
// 计算表面积的成员函数calcArea
virtual double calcArea() = 0;
// 计算体积的成员函数calcVolume
virtual double calcVolume() = 0;
};
// 定义派生类Cube，继承自Shape
class Cube : public Shape {
private:
double sideLength;
public:
// 构造函数
Cube(double sideLength) {
this->sideLength = sideLength;
}
// 计算表面积
double calcArea() override {
return 6 * sideLength * sideLength;
}
// 计算体积
double calcVolume() override {
return sideLength * sideLength * sideLength;
}
};
// 定义派生类Cylinder，继承自Shape
class Cylinder : public Shape {
private:
double height;
public:
// 构造函数
this->height = height;
}
// 计算表面积
double calcArea() override {
}
// 计算体积
double calcVolume() override {
}
};
// 定义派生类Sphere，继承自Shape
class Sphere : public Shape {
private:
public:
// 构造函数
}
// 计算表面积
double calcArea() override {
}
// 计算体积
double calcVolume() override {
return (4.0 / 3.0) * M_PI * pow(radius, 3);
}
};
// 测试主函数，使用指针数组和循环调用基类的成员函数
int main() {
Shape* shapes[] = {
new Cube(2.0),
new Cylinder(1.0, 3.0),
new Sphere(1.5)
};
int numShapes = sizeof(shapes) / sizeof(shapes[0]);
for (int i = 0; i < numShapes; ++i) {
cout << "Shape " << i+1 << ", Area: " << shapes[i]->calcArea()
<< ", Volume: " << shapes[i]->calcVolume() << endl;
delete shapes[i];
}
return 0;
}

#include<string>
#include<iostream>
using namespace std;
#define pi 3.1415926
class Shap
{
public:
virtual void area()=0;
virtual void volume()=0;
41
};
class Cube:public Shap//正方体
{
private:
float side_length;
public:
Cube(float Side_length):side_length(Side_length){}
void area()
{
cout<<"正方体表面积是："<<6*pow(side_length,2)<<endl;
}
void volume()
{
cout<<"正方体体积是："<<pow(side_length,3)<<endl;
}
};
class Cylinder:public Shap//圆柱体
{
private:
float r;
float h;
public:
Cylinder(float H,float R):r(R),h(H){}
void area()
{
cout<<"圆柱体表面积是："<<2*pi*pow(r,2)+4*pi*r*h<<endl;
}
void volume()
{
cout<<"圆柱体体积是："<<pi*pow(r,2)*h<<endl;
}
};
class Sphere:public Shap//球体
{
private:
float r;
public:
Sphere(float R):r(R){}
void area()
{
cout<<"球体表面积是："<<4*pi*pow(r,2)<<endl;
}
void volume()
{
cout<<"球体体积是："<<4*pi*pow(r,3)/3<<endl;
}
};
#include "stdafx.h"
#include<iostream>
#include<stdlib.h>
#include <stdio.h>
#include "class.h"
using namespace std;
void main(void)
{
Shap *p;
int n;//形状
char op;//操作
float side_length;
float r;
float h;
bool flag=1;
cout<<"请选择形状："<<endl;
cout<<"1：正方体"<<endl;
cout<<"2：圆柱体"<<endl;
cout<<"3：球体"<<endl;
// cin>>n;
loop: cout<<"-------------------------------------"<<endl;
while(cin>>n)
{
switch(n)
{
case 1://正方体
44
cout<<"请输入边长：";
cin>>side_length;
p=new Cube(side_length);
cout<<"-------------------------------------"<<endl;
cout<<"请选择操作："<<endl;
cout<<"a：表面积"<<endl;
cout<<"b：体积"<<endl;
cout<<"c：返回"<<endl;
while(cin>>op)
{
switch(op)
{
case 'a':
p->area();
break;
case 'b':
p->volume();
break;
case 'c':
goto loop;
default:
cerr<<"输入错误！"<<endl;
}
}
break;
case 2://圆柱体
cout<<"请输入半径：";
cin>>r;
cout<<endl;
cout<<"请输入高：";
cin>>h;
p=new Cylinder(r,h);
cout<<"-------------------------------------"<<endl;
cout<<"请选择操作："<<endl;
cout<<"a：表面积"<<endl;
cout<<"b：体积"<<endl;
cout<<"c：返回"<<endl;
while(cin>>op)
{
switch(op)
{
case 'a':
p->area();
break;
case 'b':
p->volume();
break;
case 'c':
goto loop;
default:
cerr<<"输入错误！"<<endl;
}
}
break;
case 3://球体
cout<<"请输入半径：";
cin>>r;
p=new Sphere(r);
cout<<"-------------------------------------"<<endl;
cout<<endl;
cout<<"请选择操作："<<endl;
cout<<"a：表面积"<<endl;
cout<<"b：体积"<<endl;
cout<<"c：返回"<<endl;
while(cin>>op)
{
switch(op)
{
case 'a':
p->area();
break;
case 'b':
p->volume();
break;
case 'c':
goto loop;
default:
cerr<<"输入错误！"<<endl;
}
}
break;
}
}
}

## p1876.10

#include <iostream>
using namespace std;
class Base {//定义了一个Base类
public:
virtual void Set(int b) {//虚函数的使用
x = b;
}
virtual int Get() {
return x;
}
private://定义私有类
int x;
};
class Derived: public Base {
public:
void Set(int d) {
y = d;
}
int Get() {
return y;
}
private:
int y;
};
int main() {
Base B_obj;
Derived D_obj;
Base *p = & B_obj;
p->Set(100);
cout << "B_obj x=" << p->Get() << endl;
p = &D_obj;
p->Set(200);
cout << "D_obj x=" << p->Get() << endl;
p->Base::Set(300);
cout << "B_obj x=" << p->Base::Get() << endl;
p->Set(p->Get() + 200);
cout << "D_obj y=" << p->Get() << endl;
}

这段代码是一个简单的继承示例，其中Base类作为基类，具有一个虚函数Set()和一个虚函数Get()，分别用于设置和获取私有成员变量x的值。
Derived类从Base派生，并覆盖了Set()和Get()函数，引入了新的私有成员变量y。由于这两个函数在Base中被声明为虚函数，则它们在Derived中也是虚函数。


Derived d;
d.Set(100); // 修改 y 的值



Base* p = &d;
p->Set(100); // 修改 x 的值（Base 类中的私有成员变量）




Base中的x成员变量被设置为私有成员，因此只能通过Set()和Get()函数进行访问。在Derived类中并没有直接访问Base类的私有成员变量，而是引入了新的私有成员变量y，这样保证了数据的封装性。

GUI界面编程：GUI控件是很常见的面向对象应用，例如按钮、文本框、菜单栏等都可以设计为独立的类，然后利用继承和虚函数来实现其共性和特性。

## 思考题

class Animal{

    public:

        virtual void eat() = 0;

};

class Dog : public Animal{

    public:

        void eat(){

            cout << "狗吃骨头" << endl;

        }

};

class Cat : public Animal{

    public:

        void eat(){

            cout << "猫吃鱼" << endl;

        }

};

int main(){

    Animal *animal1 = new Dog();

    animal1->eat();  // 输出：“狗吃骨头”

    Animal *animal2 = new Cat();

    animal2->eat();  // 输出：“猫吃鱼”

    delete animal1;

    delete animal2;

    return 0;

}

class Shape{

    public:

        virtual ~Shape(){}

};

class Rectangle : public Shape{

    public:

        ~Rectangle(){

            cout << "销毁矩形" << endl;

        }

};

class Triangle : public Shape{

    public:

        ~Triangle(){

            cout << "销毁三角形" << endl;

        }

};

int main(){

    Shape *shape1 = new Rectangle();

    Shape *shape2 = new Triangle();

    delete shape1;  // 输出：“销毁矩形”

    delete shape2;  // 输出：“销毁三角形”

    return 0;

}

class Color{

    public:

        void setColor(string c){

            color = c;

        }

        string getColor() const{

            return color;

        }

    private:

        string color;

};

class Pattern{

    public:

        void setPattern(string p){

            pattern = p;

        }

        string getPattern() const{

            return pattern;

        }

    private:

        string pattern;

};

class Shape{

    public:

        virtual double area() const = 0;

        virtual void print() const = 0;

};

class Graphic : public Shape, public Color, public Pattern{

    public:

        void print() const{

            cout << "形状：" << endl;

            Shape::print();

            cout << "颜色：" << getColor() << endl;

            cout << "图案：" << getPattern() << endl;

        }

};

|
13天前
|

【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
18 1
|
2天前
|
C++
C++ : 程序设计简单实例
C++ : 程序设计简单实例
9 3
|
2天前
|

C++：程序设计实例
C++：程序设计实例
8 2
|
2天前
|
C++
C++：多态性
C++：多态性
10 2
|
9天前
|
C++
c++语言核心技术要点，《运行时类型识别RTTI》
c++语言核心技术要点，《运行时类型识别RTTI》
15 2
|
14天前
|

C++课程设计实验杭州电子科技大学ACM题目（中）
C++课程设计实验杭州电子科技大学ACM题目（中）
14 1
|
8天前
|

10 0
|
14天前
|

C++课程设计实验杭州电子科技大学ACM题目（下）
C++课程设计实验杭州电子科技大学ACM题目（下）
10 0
|
14天前
|

C++课程设计实验杭州电子科技大学ACM题目（上）
C++课程设计实验杭州电子科技大学ACM题目（上）
8 0
|
1天前
|
C++
C++一分钟之-类与对象初步
【6月更文挑战第20天】C++的类是对象的蓝图，封装数据和操作。对象是类的实例。关注访问权限、构造析构函数的使用，以及内存管理（深拷贝VS浅拷贝）。示例展示了如何创建和使用Point类对象。通过实践和理解原理，掌握面向对象编程基础。
29 2