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