实验6 多态性

1.实验目的和要求:

(1)理解多态性、虚拟函数、抽象类和具体类、静态绑定和动态绑定等概念

(2)学会利用虚函数来实现多态性,以便更好地来扩展和维护系统

(3)理解C++如何实现虚拟函数和动态绑定(*)

2.实验内容:

(1)以下是一个计算正方体、球体和圆柱体的面积和体积的程序。试分析程序并写出程序的运行结果,然后上机运行验证。

#include<iostream>
using namespace std;
class container
{
protected:
    double radius;
public:
    container(double radius)
    {
        container::radius=radius;
    }
    virtual double surface_area()=0;
    virtual double volume()=0;
};
class cube:public container
{
public:
    cube(double radius):container(radius) {};
    double surface_area()
    {
        return radius*radius*6;
    }
    double volume()
    {
        return radius*radius*radius;
    }
};
class sphere:public container
{
public:
    sphere(double radius):container(radius) {};
    double surface_area()
    {
        return 4*3.1416*radius*radius;
    }
    double volume()
    {
        return 3.1416*radius*radius*radius*4/3;
    }
};
class cylinder:public container
{
    double height;
public:
    cylinder(double radius,double height):container(radius)
    {
        cylinder::height=height;
    }
    double surface_area()
    {
        return 2*3.1416*radius*(height+radius);
    }
    double volume()
    {
        return 3.1416*radius*radius*height;
    }
};
int main()
{
    container *p;
    cube obj1(10);
    sphere obj2(6);
    cylinder obj3(4,5);
    p=&obj1;
    cout<<"输出结果:"<<endl;
    cout<<"正方体表面积:"<<p->surface_area()<<endl;
    cout<<"正方体体积:"<<p->volume()<<endl;
    p=&obj2;
    cout<<"球体表面积:"<<p->surface_area()<<endl;
    cout<<"球体体积:"<<p->volume()<<endl;
    p=&obj1;
    p=&obj3;
    cout<<"圆柱体表面积:"<<p->surface_area()<<endl;
    cout<<"圆柱体体积:"<<p->volume()<<endl;
    return 0;
}
/*输出结果:
正方体表面积:600
正方体体积:1000
球体表面积:452.39
球体体积:904.781
圆柱体表面积:226.195
圆柱体体积:251.328
*/


(2)实现下图中的Shape层次结构。每个TwoDimensionalShape类应包括成员函数getArea,以计算二维图形的面积。每个ThreeDimensionalShape类包含成员函数getArea和getVolume,分别计算三维图形的表面积和体积。编写一个程序,使用层次结构中每个具体类的对象的Shape向量指针。程序要打印出向量元素所指的对象。同样,再将所有形状存入向量的循环中,要能判断每个图形到底属于TwoDimensionalShape还是属于ThreeDimenionalShape。如果某个图形是TwoDimensionalShape就显示其面积,如果某个图形是ThreeDimenionalShape,则显示其面积和体积。

#include<iostream>
using namespace std;
//-----------------类的定义---------------------------
class Shape   //是Shape成为包含接口的抽象类
{
public:
    virtual double getArea()=0;
    virtual double getVolume()=0;
    virtual void printName()=0;//定义为纯虚函数,打印对象名
    virtual void print()=0;//打印数据成员
    virtual int getcount()=0;//返回维数
};
//-----------------二维图像类的定义------------------
class TwoDimensionalShape:public Shape
{
public:
    virtual double getArea()=0;//定义计算面积的函数为纯虚函数
    virtual double getVolume()
    {
        return 0;
    };
    void printName()
    {
        cout<<"TwoDimensionalShape: ";
    }
    void print()
    {
        cout<<"is a two dimension shape!"<<endl;
    }

};
//--------------------三维图像类的定义------------------
class ThreeDimensionalShape:public Shape
{
public:
    virtual double getArea()=0;//定义计算面积的函数为纯虚函数
    virtual double getVolume()=0;//定义计算体积的函数为纯虚函数
    void printName()
    {
        cout<<"ThreeDimensionalShape: ";
    }
    void print()
    {
        cout<<"is a three dimension shape!"<<endl;
    }
};
//----------------圆类----------------------
class Circle:public TwoDimensionalShape
{
private:
    double radius;
public:
    Circle(double a)//构造函数
    {
        this->radius=a;
    }
    double getArea()    //返回圆的面积
    {
        return 3.14*radius*radius;
    }
    void printName()
    {
        cout<<"Circle ";
    }
    void point()
    {
        TwoDimensionalShape::print();
        cout<<"; Radius="<<radius<<endl;
    }
    int getcount()//返回维数
    {
        return 2;
    }

};
//-----------------三角形类---------------------
class Triangle:public TwoDimensionalShape
{
private:
    double length,height;//三角形的底和高

public:
    Triangle(double a,double b)
    {
        this->length=a;
        this->height=b;
    }
    double getArea()//三角形的面积
    {
        return (length*height)/2;
    }
    void printName()
    {
        cout<<"Triangle ";
    }
    void point()
    {
        TwoDimensionalShape::print();
        cout<<"; length="<<length<<",height="<<height<<endl;
    }
    int getcount()//三角形的维数
    {
        return 2;
    }
};

//-------------------正方形--------------
class Square:public TwoDimensionalShape
{
private:
    double length;//正方形的
public:
    Square(double a)
    {
        this->length=a;
    }
    double getArea()//正方形的面积
    {
        return length*length;
    }
    void printName()
    {
        cout<<"Square ";
    }
    void point()
    {
        TwoDimensionalShape::print();
        cout<<"; length="<<length<<endl;
    }
    int getcount()
    {
        return 2;
    }
};

//-------------定义球类-------------------
class Sphere:public ThreeDimensionalShape
{
private:
    double radius;
public:
    Sphere(double a)
    {
        this->radius=a;
    }
    double getArea()
    {
        return 4*3.14*radius*radius;
    }
    double getVolume()
    {
        return (4*3.14*radius*radius*radius)/3;
    }
    void printName()
    {
        cout<<"Sphere ";
    }
    void point()
    {
        ThreeDimensionalShape::print();
        cout<<"; Radius="<<radius<<endl;
    }
    int getcount()
    {
        return 3;
    }
};
//---------------定义正方体类-------------------
class Cube:public ThreeDimensionalShape
{
private:
    double length;
public:
    Cube(double a)
    {
        this->length=a;
    }
    double getArea()//计算正方体面积
    {
        return length*length*6;
    }
    double getVolume()//计算正方体的体积
    {
        return length*length*length;
    }
    void printName()
    {
        cout<<"Square ";
    }
    void point()
    {
        ThreeDimensionalShape::print();
        cout<<"; length="<<length<<endl;
    }
    int getcount()
    {
        return 3;
    }
};
//-----------函数实现--------------------------------------
void Pointer1(Shape*); //情况一,指针
void Pointer2(Shape&); //情况二,引用
//-----------外部函数实现----------------------------------
void Pointer1(Shape* baseClassptr)
{
    int i;
    i=baseClassptr->getcount();
    cout<<"----------------------------------"<<endl;
    baseClassptr->printName();
    baseClassptr->print();
    //要能判断每个图形到底属于TwoDimensionalShape还是属于ThreeDimenionalShape
//是TwoDimensionalShape就显示其面积
    if(i=2)
    {
        cout<<"Area="<<baseClassptr->getArea()<<endl;
    }
//是ThreeDimenionalShape,则显示其面积和体积
    else
    {
        cout<<"Area="<<baseClassptr->getArea()<<endl;
        cout<<"Volume="<<baseClassptr->getVolume()<<endl;
    }
}
void Pointer2(Shape& baseClassptr)
{
    int i;
    i=baseClassptr.getcount();
    cout<<"----------------------------------"<<endl;
    baseClassptr.printName();
    baseClassptr.print();
    //要能判断每个图形到底属于TwoDimensionalShape还是属于ThreeDimenionalShape
//是TwoDimensionalShape就显示其面积
    if(i=2)
    {
        cout<<"Area="<<baseClassptr.getArea()<<endl;
    }
//是ThreeDimenionalShape,则显示其面积和体积
    else
    {
        cout<<"Area="<<baseClassptr.getArea()<<endl;
        cout<<"Volume="<<baseClassptr.getVolume()<<endl;
    }
}

int main()
{
//打印所指对象
    Shape* pShape;//定义Shape类型的指针
    Circle circle(1.0);
    Triangle triangle(2.0,3.0);
    Square square(4.0);
    Sphere sphere(6.0);
    Cube cube(7.0);
    pShape=&circle;
    pShape->printName();
    pShape->print();
    pShape=▵
    pShape->printName();
    pShape->print();
    pShape=□
    pShape->printName();
    pShape->print();
    pShape=&sphere;
    pShape->printName();
    pShape->print();
    pShape=&cube;
    pShape->printName();
    pShape->print();
//将所有形状存入向量的循环中
    Shape* arrayOfshape[5];
    arrayOfshape[0]=&circle;
    arrayOfshape[1]=▵
    arrayOfshape[2]=□
    arrayOfshape[3]=&sphere;
    arrayOfshape[4]=&cube;
    for(int i=0; i<5; i++)
        Pointer1(arrayOfshape[i]);
    for(int i=0; i<5; i++)
        Pointer2(*arrayOfshape[i]);
}

(3)编写一个程序,先设计一个链表List类,再从链表类派生出一个集合类Set类,再集合类中添加一个记录元素个数的数据项。要求可以实现对集合的插入、删除、查找和显示。

#include<iostream>
using namespace std;
struct ListNode   //结点结构体
{
    ListNode* Next;
    int num;
};
//-------------------List类-------------------------------
class List
{
private:
    ListNode *phead;
public:
    List()
    {
        this->phead=NULL;   //构造函数
    }
    ~List()//析构函数
    {
        while(this->phead)
        {
            ListNode* temp=phead;
            phead=phead->Next;
            delete temp;
        }
    }
    virtual void Insert(int a)//初始化并构建链表,头结点为空则首先建立新节点,若不为空则直接插入
    {
        ListNode* temp;
        if(this->phead==NULL)
        {
            phead=new ListNode;
            phead->num=a;
            phead->Next=NULL;
        }
        else
        {
            temp=new ListNode;
            temp->num=a;
            temp->Next=phead;
            phead=temp;
        }
    }
    virtual void Remove(int y)//将数值为a的节点删除
    {
        int tag=0;
        ListNode* temp;
        temp=phead;
        while(temp)
        {
            if(temp->num==y)
            {
                tag++;
                break;
            }
            temp=temp->Next;
        }
        //如果tag不等于则说明在链表中有
        if(tag!=0)
        {
            int i;
            i=phead->num;
            phead->num=temp->num;
            temp->num=i;
            ListNode* p=phead;
            phead=phead->Next;
            delete p;
        }
        else
            cout<<y<<" is not in Set!"<<endl;
    }
    virtual void Find(int a)//查找值为a的节点所在的位置
    {
        int tag=0;//位置标志
        ListNode* head=phead;//定义一个指针,并赋值为头指针
        while(head)
        {
            if(head->num==a) break;
            else
            {
                tag++;
                head=head->Next;
            }
        }
        //return head;//找到a则返回a的位置
        if(tag==0||(tag+1)>Listlength())
            cout<<a<<" is not exist!"<<endl;
        else
            cout<<a<<" is the "<<tag+1<<"th number in all!"<<endl;
    }
    virtual void Print()
    {
        ListNode* head=phead;//定义一个指针,并赋值为头指针
        if(head==NULL)
            cout<<"The list is empty!"<<endl;
        while(head)
        {
            cout<<head->num<<" ";
            head=head->Next;
        }
        cout<<endl;
    }
    int Listlength()//求得链表的长度
    {
        int i=0;
        ListNode* head=phead;
        while(head)
        {
            i++;
            head=head->Next;
        }
        cout<<"The length of List is "<<i<<endl;
        return i;
    }
    ListNode* get()//返回链表头结点
    {
        return phead;
    }
};

//-----------------------Set类----------------------------
class Set : public List
{
private:
    static int count;
public:
    ~Set()
    {
        count--;
    }
    void Insert(int x)//在集合中插入数据,首先判断数据是否已经存在,若是存在则不插入数据
    {
        ListNode* temp;
        temp=List::get();//指向头结点
        int tag=0;
        while(temp)
        {
            if(temp->num==x)
            {
                tag=tag+1;
                cout<<"This number "<<x<<" already exists!"<<endl;
                break;
            }
            temp=temp->Next;
        }
        if(tag==0)
        {
            List::Insert(x);
            count++;
        }
    }
    void Remove(int y)//在集合中删除y,调用List的Remove函数,若y在链表中,则删除
    {
        List::Remove(y);
        count--;
    }
    void Find(int z)//查找z值所在位置
    {
        List::Find(z);
    }
    void Print()//显示集合中数据
    {
        List::Print();
        cout<<"The total number of the data is "<<count<<endl;
    }

};
int Set::count=0;

int main()
{
    List* p;
    Set t;
    p=&t;
//------------插入数据---------------
    p->Insert(2);
    p->Insert(3);
    p->Insert(4);
    p->Insert(5);
//------------删除数据---------------
    p->Remove(8);
    p->Remove(6);
    p->Remove(2);
    p->Insert(6);
    p->Insert(7);
//------------显示数据---------------
    p->Print();
//------------查找相应的数据---------
    p->Find(3);
}

你可能感兴趣的:(C++)