目 录
实验1 编程环境的熟悉及简单 C++程序的编制 1
1.1 实验目的和要求 1
1.2 所占学时数 1
1.3 实验任务(实验指导书中涂红色的部分) 1
1.3.1 任务一 1
1.3.1 任务二 4
实验2 函数的应用 6
2.1 实验目的和要求 6
2.2 所占学时数 6
2.3 实验任务(实验指导书中涂红色的部分) 6
2.3.1 任务一 6
2.3.1 任务二 8
实验3 类与对象、构造与析构函数 12
3.1 实验目的和要求 12
3.2 所占学时数 12
3.3 实验任务(实验指导书中涂红色的部分) 12
3.3.1 任务一 12
实验4 数据共享与保护 16
4.1 实验目的和要求 16
4.2 所占学时数 16
4.3 实验任务(实验指导书中涂红色的部分) 16
4.3.1 任务一 16
实验5 数组、指针与字符串 20
5.1 实验目的和要求 20
5.2 所占学时数 21
5.3 实验任务(实验指导书中涂红色的部分) 21
5.3.1 任务一 21
实验6 类的继承与派生 27
6.1 实验目的和要求 27
6.2 所占学时数 27
6.3 实验任务(实验指导书中涂红色的部分) 27
6.3.1 任务一 27
实验7 多态性 34
7.1 实验目的和要求 34
7.2 所占学时数 34
7.3 实验任务(实验指导书中涂红色的部分) 34
7.3.1 任务一 34
实验1 编程环境的熟悉及简单 C++程序的编制
1.1 实验目的和要求
1.熟悉 VS2010 编程环境,编制简单 C++程序并运行,熟悉 C++的编辑、 编译、 连
接、运行、断点调试等过程。
2.掌握 C++数据类型,熟悉如何定义和使用常量和变量,以及对它们赋值的方法。
3.学会使用 C++的有关算术运算符及表达式,特别是自加(++)和自减(--)运算符
的使用。
4.分支和循环结构的使用
1.2 所占学时数
2个实验课时
1.3 实验任务
注:实验任务中涂红色的部分
1.3.1 任务一
(1)题目名称
功能需求:运行时显示"Menu: A(dd) D(elete) S(ort) Q(uit), Select one:"提示用户输入,A 表示增加,D 表示删除,S 表示排序,Q 表示退出,输入为 A、 D、S 时分别提示"数据已经增加、删除、排序。"输入为 Q 时程序结束。
按照上述功能需求写两个程序,分别使用if分支语句和switch分支语句实现:
程序1要求:使用 if … else 语句进行判断,用 break、continue 控制程序流程。
程序2要求:使用 Switch 语句实现。
(2)构思过程(可用文字、流程图、UML图等方式表达)
读取输入的字符,在while循环中通过if语句或switch语句判断输入的字符,然后输出对应的提示。
(3)程序源码
程序1:
#include
using namespace std;
int main()
{
string s;
cout << "Menu: A(dd) D(elete) S(ort) Q(uit), Select one:" << endl;
cin >> s;
while (s != "Q" )
{
if (s=="Q")
{
break;
}
else if (s=="A")
{
cout << "数据已经增加"<
cin >> s;
continue;
}
else if (s=="D")
{
cout << "数据已经删除" << endl;
cin >> s;
continue;
}
else if (s=="S")
{
cout << "数据已经排序" << endl;
cin >> s;
continue;
}
}
程序2:
#include
using namespace std;
int main()
{
char s;
cout << "Menu: A(dd) D(elete) S(ort) Q(uit), Select one:" << endl;
cin >> s;
while (s != 'Q')
{
switch (s)
{
case'A':
{
cout << "数据已经增加" << endl;
break;
}
case'D':
{
cout << "数据已经删除" << endl;
break;
}
case'S':
{
cout << "数据已经排序" << endl;
break;
}
}cin >> s;
}
}
(4)运行结果(截图)
程序1:
程序2:
(5)心得体会
实现同一种功能的程序可能不止一种写法,例如for语句与while语句虽然一个是已知次循环,一个是未知次循环,但两者在特定情况下可以替换,if语句和switch语句在本实验中相互替换也说明了这个道理。
1.3.1 任务二
(1)题目名称
找出2~10000之内的所有完全数。所谓完全数,即其各因子之和正好等于本身的数。如6=1+2+3,28=1+2+4+7+14,所以6,28都是完全数
(2)构思过程(可用文字、流程图、UML图等方式表达)
构造一个返回值为参数所以因子之和的函数,其中因子由求余运算得到,在主函数中将返回值与参数对比,如果相等,即为完全数,可通过for循环依次找到2~10000之内的所以完全数。
(3)程序源码
#include
using namespace std;
int Wanquan(int num)
{
int n = num / 2;
int sum = 0;
for (int i = 1; i <=n; i++)
{
if (num%i==0)
{
sum += i;
}
}
return sum;
}
int main()
{
for (int i = 2; i <= 10000; i++)
{
if (Wanquan(i)==i)
{
cout << i<
}
}
}
(4)运行结果(截图)
(5)心得体会
为了实现特定的功能,可以构造一个特定的函数,这样不仅减少了代码的编写,同样缩短了程序运行的时间,大大提高了运行效率。
实验2 函数的应用
2.1 实验目的和要求
1.掌握函数声明、定义和调用的方法;
2.掌握函数递归调用的方法;
3.掌握重载函数的声明、定义和使用方法;
4.理解函数参数传递中传值与引用的区别。
2.2 所占学时数
2个实验课时
2.3 实验任务(实验指导书中涂红色的部分)
2.3.1 任务一
(1)题目名称
用递归方法编写函数 Fibonnacci(斐波那契)级数:
并求出第 26 项的值。
(2)构思过程(可用文字、流程图、UML图等方式表达)
构造一个名为Fibonnacci的函数,在其中实现f3=f1+f2,f1=f2,f2=f3.的循环运算,然后返回f3,在主函数中输出返回值。
(3)程序源码
#include
using namespace std;
int Fibonnacci(int mun)
{
int f1 = 1;
int f2 = 1;
int f3 = 0;
int f = 0;
if (mun==1||mun==2)
{
return 1;
}
else
{
for (size_t i = 2; i < mun; i++)
{
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
return f3;
}
}
int main()
{
cout<< Fibonnacci(26);
}
(4)运行结果(截图)
(5)心得体会
在使用递归函数时,要考虑到n=1,n=2时的情况,以防出现错误。
2.3.1 任务二
(1)题目名称
设计一函数,判断一整数是否为素数。并完成下列程序设计:
①编写求素数的函数,并用这个函数求 3-200 之间的所有素数
②在 4-200 之间,验证歌德巴赫猜想:任何一个充分大的偶数都可以表示为两个素数之
和。输出 4=2+2 6=3+3 …… 200=3+197
注:素数又称质数,指在一个大于 1 的自然数中,除了 1 和此整数自身外,不能被其
他自然数(不包括 0)整除的数。
(2)构思过程(可用文字、流程图、UML图等方式表达)
构造一个判断参数是否为素数的函数,其中包含for循环以及if语句,判断参数能否整除给定范围内的某个数,以此来判断该参数是否为素数,在主函数中通过for循环判断3~200内的素数,并输出。
在for循环中将某个偶数循环减去i,判断减数与差是否均为素数,以及是否重复,如果条件均满足,则输出。
(3)程序源码
#include
#include
using namespace std;
int Su(int num)
{
bool flag = true;
if (num==2)
{
return 2;
}
else
{
for (size_t i = 2; i <= sqrt(num); i++)
{
if (num % i == 0)
{
flag = false;
break;
}
}if (flag)
{
return num;
}
else
{
return 0;
}
}
}
int main()
{
for (int i = 3; i <= 200; i++)
{ if (i==200)
{
cout << endl;
}
if (Su(i)==0)
{
continue;
}
else
{
cout << Su(i) << " ";
}
}int v = 0;
for (int i = 4; i <= 200; i++)
{
if (i%2!=0)
{
continue;
}
else
{
for (int j = 197; j >=2; j--)
{
if (Su(j)==j)
{
int x;
x = i - j;
if (Su(x)==x&&j<=x)< span="">
{
cout << i << "=" << j << "+" << x< ";
v++; if (v%5==0)
{
cout << endl;
}
}
else
{
continue;
}
}
}
}
}
}
(4)运行结果(截图)
(5)心得体会
在判断参数是否为素数n的函数中,for循环次数可设定为n^(1/2),缩减运行时间,以防超时,
实验3 类与对象、构造与析构函数
3.1 实验目的和要求
1.掌握类的定义和使用
2.掌握对象的定义和对象的声明。
3.掌握具有不同访问属性的成员的访问方式。
4.深入体会构造函数、复制构造函数、析构函数的执行机制。
5.使用的 VS的 断点调试功能观察程序流程,跟踪观察类的构造函数、析构函数、 成
员函数的执行顺序。
3.2 所占学时数
4个实验课时
3.3 实验任务(实验指导书中涂红色的部分)
3.3.1 任务一
(1)题目名称
设计一个用于人事管理的 People(人员)类。考虑到通用性,这里只抽象出所有类型 人员都具有的属性:number(编号)、sex(性别)birthday(出生日期)、id(身份证号)等。
其中"出生日期"定义为一个"日期"类内嵌子对象。用成员函数实现对人员信息 的录入和显示。
要求包括:构造函数和析构函数、拷贝构造函数、内联成员函数、带缺省形参值的成员函数 。
(2)构思过程(可用文字、流程图、UML图等方式表达)
先要构建一个Date类,来为之后的People类提供内嵌对象,然后设计People类,声明编号、性别、身份证号为私有成员,声明共有的构造函数、复制构造函数、析构函数、无返回值的input函数、output函数来对编号、性别、出生日期、身份证号进行赋值以及对应的输出。
(3)程序源码
#include
#include
using namespace std;
class Date
{
private:
int year,month,day;
public:
Date() {};
Date(int y, int m, int d)
{
year = y;
month = m;
day = d;
}
void set()
{
cin >> year >>month >> day;
}
void display()
{
cout << year << "年" << month << "月" << day << "日";
}
};
class People
{
private:
int num;
string sex;
Date birthday;
string Id;
public:
People() {}
People(int n,int y, int m, int d, string id, string s = "男") :birthday(y, m, d)
{
num = n;
sex = s;
Id = id;
}
People( People& p)
{
num = p.num;
sex = p.sex;
birthday = p.birthday;
Id = p.Id;
}
void input()
{
cout << "录入:" << endl;
cout << "编号:";
cin >> num;
cout << "性别:";
cin >> sex;
cout << "生日:";
birthday.set();
cout << "身份证号:";
cin >> Id;
}
void output()
{
cout << "编号" << num << endl;
cout << "性别" << sex << endl;
cout << "生日";
birthday.display();
cout << endl;
cout << "身份证号" << Id << endl;
}
~People()
{
cout << " " << num << "号人员已经录入" << endl;
}
};
int main()
{
People p1;
People p2(01,2000,12,13,"130635200012132028","男");
p2.output();
p1.input();
p1.output();
}
(4)运行结果(截图)
(5)心得体会
在编写一个类的时候,要有一个基本框架,要清楚要声明几个对象、实现什么功能,要明白使用内嵌对象时的参数传递过程
实验4数据共享与保护
4.1 实验目的和要求
1.观察程序运行中变量的作用域、生存期。
2.学习类的静态成员的使用。
3.理解类的友元函数、友元类。
4. 学习多文件结构在 C++程序中的使用。
4.2 所占学时数
2个实验课时
4.3 实验任务(实验指导书中涂红色的部分)
4.3.1 任务一
(1)题目名称
定义一个 Girl 类和一个 Boy 类,这两个类中都有表示姓名、年龄的私有成员变量,都要定义构造函数、析构函数、输出成员变量信息的公有成员函数。
1.根据要求定义相应的类;
2.将 Girl 类作为 Boy 类的友元类,在 Girl 类的成员函数visitboy(boy &)中访问 boy 类的私有成员,观察程序运行结果;
3.在 boy 类的某成员函数 visitgirl(girl &)中试图访问 girl 类的私有成员,观察编译器给
出的错误信息,理解友元的不可逆性;
4.主函数中正确定义两个类的对象,调用各自的成员函数实现相应的功能
5.再将 boy 类作为 girl 类的友元类,在 boy 类的某成员函数visistgirl(girl &)中访问 girl
类的私有成员,观察编译器给出的信息;
6. 删除两个类中的函数 visitgirl(girl &),visitboy(boy &) ,定义一个顶层函数
visitboygirl(boy &,girl &),作为以上两个类的友元,通过调用该函数输出男孩和女孩的信息。
(2)构思过程(可用文字、流程图、UML图等方式表达)
构建Girl类和Boy类,其中姓名、年龄设为私有,声明对应的构造函数、析构函数、无返回值的show函数,在类外完成各自函数的实现,
访问其他类的私有成员时要先声明该类为其他类的友元,再完成对应visitgirl(boy)函数的声明及实现,visitboygirl(boy &,girl &)的使用,要提前在两个类中声明对应的友元函数。
(3)程序源码
#include
using namespace std;
class Boy;
class Girl
{
friend Boy;
friend void visitboygirl(Boy& boy, Girl& girl);
private:
string name;
int age;
public:
Girl(string s, int x);
~Girl() {};
void show() ;
void visitBoy(Boy&boy);
};
class Boy
{
friend Girl;
friend void visitboygirl(Boy& boy, Girl& girl);
private:
string name;
int age;
public:
Boy(string s, int x);
~Boy() {};
void show();
void visitgirl(Girl&girl);
};
Boy::Boy(string s, int x)
{
name = s;
age = x;
}
void Boy::show()
{
cout << "BOY's name is " << name << endl;
cout << "BOY's age is " << age << endl;
}
Girl::Girl(string s, int x)
{
name = s;
age = x;
}
void Girl::show()
{
cout << "GIRL's name is " << name << endl;
cout << "GIRL's age is " << age << endl;
}
void visitboygirl(Boy &boy, Girl& girl)
{
cout << "Boy : " << boy.name << " " << boy.age << endl;
cout << "Girl : " << girl.name << " " << girl.age << endl;
}
void Girl::visitBoy(Boy &boy)
{
cout << "Boy : " <
}
void Boy::visitgirl(Girl &girl)
{
cout << "Girl : " <
}
int main()
{
Girl b("giil",21);
Boy a("booy",23);
b.visitBoy(a);
a.visitgirl(b);
visitboygirl(a, b);
}
(4)运行结果(截图)
从girl类访问boy类私有成员(已声明友元类)
从boy类访问girl类私有成员(未声明友元类)
从boy类访问girl类私有成员(已声明友元类)
声明类girl和boy的友元函数,访问类的私有成员
(5)心得体会
如果遇到使用了未声明类的对象时,要先声明类的存在。
如果想要访问其他类的私有成员,要声明为该类的友元
实验5数组、指针与字符串
5.1 实验目的和要求
1.学习使用数组。
2.掌握指针的使用方法,体会运算符&、*的不同作用。
3. 学习字符串数据的组织和处理。
4. 练习通过动态分配内存实现动态数组,并体会指针在其中的作用。
5.分别使用字符数组和标准 C++库练习处理字符串的方法。
5.2 所占学时数
4个实验课时
5.3 实验任务(实验指导书中涂红色的部分)
5.3.1 任务一
(1)题目名称
编写 C++程序完成以下功能:
用类来实现矩阵,定义一个矩阵的类,属性包括:
矩阵大小,用 lines, rows(行、列来表示);存贮矩阵的数组指针,根据矩阵大小动态申请(new)。
矩阵类的方法包括:
构造函数:参数是矩阵大小,需要动态申请存贮矩阵的数组;
析构函数:需要释放矩阵的数组指针;
拷贝构造函数:需要申请和复制数组(深复制);
输入函数:可以从 cin 中输入矩阵元素;
输出函数:将矩阵格式化输出到 cout;
矩阵相加函数:实现两个矩阵相加的功能,结果保存在另一个矩阵里,但必须矩阵大小相同;
矩阵相减的函数:实现两个矩阵相减的功能,结果保存在另一个矩阵里,但必须矩阵大小相同。
主函数功能:
定义三个矩阵:A1、A2、A3;
初始化 A1、A2;
计算并输出 A3 = A1+A2;
用 new 动态创建三个矩阵类的对象:pA1、pA1、pA3;
初始化 pA1、pA2;
计算并输出 pA3=pA1+pA2,pA3=pA1-pA2;
释放 pA1、pA1、pA3。
(2)构思过程(可用文字、流程图、UML图等方式表达)
构建一个rectangle类,声明私有成员lines、rows、size,声明该类的构造函数、复制构造函数、析构函数、创建一个size大小的指针类型的数组
编写实现数组元素输入、输出、相加、相减的in、out、add、sub函数
(3)程序源码
#include
using namespace std;
class rectangle
{
int lines, rows, size;
public:
int* p;
rectangle();
rectangle(int x, int y);
~rectangle();
rectangle(const rectangle&r);
void in();
void out();
rectangle add(rectangle s);
rectangle sub(rectangle s);
};
rectangle::rectangle()
{
lines = rows = 3;
size = 9;
p = new int[9];
}
rectangle::rectangle(int x, int y)
{
lines = x;
rows = y;
size = lines * rows;
p = new int[size];
}
rectangle::~rectangle()
{
delete[]p;
}
rectangle::rectangle( const rectangle&r)
{
lines = r.lines;
rows = r.rows;
size = r.size;
p = new int[size];
for (size_t i = 0; i < r.size; i++)
{
p[i] = r.p[i];
}
}
void rectangle::in()
{
for (size_t i = 0; i < lines; i++)
{
for (size_t j = i*rows; j < i*rows+rows; j++)
{
cin >> p[j];
}
}
}
void rectangle::out()
{
for (size_t i = 0; i < lines; i++)
{
for (size_t j = i * rows; j < i * rows + rows; j++)
{
cout << p[j] << " ";
}cout << endl;
}
}
rectangle rectangle::add(rectangle s)
{
cout << "---------------矩阵相加---------------" << endl;
rectangle a(s.lines, s.rows);
for (size_t i = 0; i < s.lines; i++)
{
for (size_t j = i*s.rows; j < i*s.rows+s.rows; j++)
{
a.p[j] = p[j] + s.p[j];
}
}
return a;
}
rectangle rectangle::sub(rectangle s)
{
cout<< "---------------矩阵相减---------------" << endl;
rectangle a(s.lines, s.rows);
for (size_t i = 0; i < s.lines; i++)
{
for (size_t j = i * s.rows; j < i * s.rows + s.rows; j++)
{
a.p[j] = p[j] -s.p[j];
}
}
return a;
}
int main()
{
rectangle a1(2, 2);
rectangle a2(2, 2);
int a[4] = { 1,2,3,4 };
for (size_t i = 0; i < 4; i++)
{
a1.p[i] = a[i];
}
for (size_t i = 0; i < 4; i++)
{
a2.p[i] = a[i];
}
cout << "----------------矩阵1---------------- "<< endl;
a1.out();
cout<< "----------------矩阵2---------------- " << endl;
a2.out();
rectangle a3 = a1.add(a2);
cout << "----------------矩阵1+矩阵2--------------- " << endl;
a3.out();
cout << "---------------输入矩阵行列大小-----------" << endl;
int x, y;
cin >> x >> y;
cout << "---------------输入矩阵1元素-------------" << endl;
rectangle pa1(x, y);
rectangle pa2(x, y);
pa1.in();
cout << "----------------矩阵1---------------- " << endl;
pa1.out();
cout << "---------------输入矩阵2元素-------------" << endl;
pa2.in();
cout << "----------------矩阵2---------------- " << endl;
pa2.out();
rectangle pa3 = pa1.add(pa2);
cout << "----------------矩阵1+矩阵2--------------- " << endl;
pa3.out();
rectangle pa4 = pa1.sub(pa2);
cout << "----------------矩阵1-矩阵2--------------- " << endl;
pa4.out();
}
(4)运行结果(截图)
(5)心得体会
要有指针去开辟动态空间,并且要记得使用delete去释放内存空间
实验6类的继承与派生
6.1 实验目的和要求
1、从深层次上理解继承与派生的关系
2、掌握不同继承方式下,从派生类/对象内部和外部对基类成员的访问控制权限。
3、掌握单继承和多继承的使用方法,尤其是派生类构造函数的声明方式。
4、掌握继承与派生下构造函数与析构函数的调用顺序。
5、理解“类型兼容”原则
6、学习利用虚基类解决二义性问题。
6.2 所占学时数
4个实验课时
6.3 实验任务(实验指导书中涂红色的部分)
6.3.1 任务一
(1)题目名称
1、编写 C++程序,以完成以下功能(具体的数据成员、函数成员,请自主定义):
(1)声明一个基类 Shape(形状),其中包含一个方法来计算面积;
(2)从 Shape 派生两个类:矩形类(Rectangle)和圆形类(Circle);
(3)从 Rectangle 类派生正方形类 Square;
(4)分别实现派生类构造函数、析构函数及其它功能的成员函数;
(5)创建各派生类的对象,观察构造函数、析构函数的调用次序;
(6)计算不同对象的面积。
2、将 1 中 Shape 基类计算面积的方法定义为虚函数,比较与【形状(一)】程序的差异,体验其优点。
(2)构思过程(可用文字、流程图、UML图等方式表达)
创建一个shape类,声明私有成员length, width,编写对应的构造函数、析构函数、计算面积的函数、输出面积的函数,以此类为基类,创造出矩形类和圆类,以矩形类为基类,创造出正方形类,比较各自差异,进行补充
(3)程序源码
程序1:
#include
using namespace std;
class shape
{
double length, width;
public:
shape()
{
length = width = 0;
}
shape(double l, double w)
{
length = l;
width = w;
cout << "创建shape" << endl;
}
~shape()
{
cout << "释放shape" << endl;
}
double area()
{
double s;
s = length * width;
return s;
}
void show()
{
cout << "shape's area is = " << area() << endl;
}
};
class rectangle :public shape
{
public:
rectangle():shape(0,0){}
rectangle(double a, double b) :shape(a, b)
{
cout << "创建rectangle" << endl;
}void show()
{
cout< area is = " << area() << endl;
}
~rectangle()
{
cout << "释放rectangle" << endl;
}
};
class square :public rectangle
{
public:
square(double a) :rectangle(a, a)
{
cout << "创建square" << endl;
}
void show()
{
cout << "square's area is = " << area() << endl;
}
~square()
{
cout << "释放square" << endl;
}
};
class circle :public shape
{
double r;
public:
circle(double rr) :shape(rr, rr)
{
r = rr;
cout << "创建circle" << endl;
}
~circle()
{
cout << "释放circle" << endl;
}
double area()
{
double s;
s = 3.14 * r * r;
return s;
}
void show()
{
cout << "circle's area is = " << area() << endl;
}
};
int main()
{
rectangle r(1, 2);
r.show();
circle c(2);
c.show();
square s(2);
s.show();
shape p(3, 4);
p.show();
}
程序2:
#include
using namespace std;
class shape
{
double length, width;
public:
shape()
{
length = width = 0;
}
shape(double l, double w)
{
length = l;
width = w;
cout << "创建shape" << endl;
}
virtual ~shape()
{
cout << "释放shape" << endl;
}
virtual double area()
{
double s;
s = length * width;
return s;
}
virtual void show()
{
cout << "area = " << area() << endl;
}
};
class rectangle :public shape
{
public:
rectangle():shape(0,0){}
rectangle(double a, double b) :shape(a, b)
{
cout << "创建rectangle" << endl;
}
~rectangle()
{
cout << "释放rectangle" << endl;
}
};
class square :public rectangle
{
public:
square(double a) :rectangle(a, a)
{
cout << "创建square" << endl;
}
~square()
{
cout << "释放square" << endl;
}
};
class circle :public shape
{
double d;
public:
circle(double r) :shape(r, r)
{
d = r;
cout << "创建circle" << endl;
}
double area()
{
double s;
s = 3.14 * d * d;
return s;
}
};
int main()
{
rectangle p(2, 2);
shape* r;
r = &p;
r->show();
circle c(2);
r = &c;
r->show();
}
(4)运行结果(截图)
(5)心得体会
若子类与父类中存在同名函数,则在从子类中调用该函数时,子类中该函数被调用,父类中同名函数被隐藏,如果子类中没有所需函数,父类中存在所需函数,则调用父类中的函数
实验7多态性
7.1 实验目的和要求
1、 掌握将运算符重载为成员函数与非成员函数的区别。
2、 掌握静态编联与动态联编的概念、区别及实现方式。
2、 掌握利用虚函数实现动态多态的方法。
3、 掌握利用纯虚函数与抽象类实现动态多态的方法。
7.2 所占学时数
2个实验课时
7.3 实验任务(实验指导书中涂红色的部分)
7.3.1 任务一
(1)题目名称
定义一个基类为哺乳动物类 mammal,其中有数据成员年龄、重量、品种,有成员函数move()、speak()、eat()等,以此表示动物的行为。由这个基类派生出狗、猫、马、猪等哺乳动物,它们都有各自的行为。编程分别使各个动物表现出不同的行为。
(2)构思过程(可用文字、流程图、UML图等方式表达)
①为实现动态联编,首先建立 Mammal 抽象类,以此抽象类作为基类,派生 dog、cat、horse、pig 类。其中 Mammal 类数据员有(姓名)name 、(年龄)age、(重量)weight。成员函数move()、eat()、speak(),定义为纯虚函数:另一个成员函数 display(),声明为虚函数。
②建立各个派生类 dog、cat、horse、pig。然后建立构造函数为其初始化。再定义函数move()、speak()、eat()等。
③main()函数中建立指向 Mammal 的指针数组,并为各派生类初始化。把指针数组分别指向各个派生类。设计一个循环来显示派生类对象的信息。
(3)程序源码
#include
#include
using namespace std;
class mammal
{
int age;
double weight;
string name;
public:
mammal(string s, double d, int a)
{
age = a;
weight = d;
name = s;
}
virtual void move() = 0;
virtual void speak() = 0;
virtual void eat() = 0;
virtual void display()
{
cout << " 种类 : " << name << endl << " 重量 : " << weight << endl << " 年龄 : " << age << endl;
}
virtual~mammal(){}
};
class dog :public mammal
{
public:
dog(string s,double d,int a):mammal(s,d,a){}
void move()
{
cout << "dog is moving" << endl;
}
void speak()
{
cout << "dog is speaking" << endl;
}
void eat()
{
cout << "dog is eating" << endl;
}
};
class cat :public mammal
{
public:
cat(string s, double d, int a) :mammal(s, d, a) {}
void move()
{
cout << "cat is moving" << endl;
}
void speak()
{
cout << "cat is speaking" << endl;
}
void eat()
{
cout << "cat is eating" << endl;
}
};
class pig :public mammal
{
public:
pig(string s, double d, int a) :mammal(s, d, a) {}
void move()
{
cout << "pig is moving" << endl;
}
void speak()
{
cout << "pig is speaking" << endl;
}
void eat()
{
cout << "pig is eating" << endl;
}
};
class horse :public mammal
{
public:
horse(string s, double d, int a) :mammal(s, d, a) {}
void move()
{
cout << "horse is moving" << endl;
}
void speak()
{
cout << "horse is speaking" << endl;
}
void eat()
{
cout << "horse is eating" << endl;
}
};
int main()
{
mammal* m[4];
dog d("dog", 15, 1);
cat c("cat", 12, 3);
pig p("pig", 23, 4);
horse h("horse", 12, 2);
for (size_t i = 0; i < 4; i++)
{
switch (i)
{
case 0:
{
m[i] = &d;
break;
}
case 1:
{
m[i] = &c;
break;
}
case 2:
{
m[i] = &p;
break;
}
case 3:
{
m[i] = &h;
break;
}
default:
break;
}
m[i]->display();
m[i]->eat();
m[i]->move();
m[i]->speak();
}
}
(4)运行结果(截图)
(5)心得体会
抽象类只能作为基类使用,虚函数能够从父类继承到子类