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); }