这是一次学校C++课程上机作业的整理,包含17道题目。
目录
2.1质因数分解
2.2矩阵旋转
2.3字符串基本操作
2.4整数加一
2.5回文字符串
3.1摄氏华氏温度转换
3.2 简易计算器
3.3时间类Time的编写
❄️4.1 矩形相交
❄️4.2成绩表里找同学
❄️4.3动态二维double型数组类Matrix的编写
⚽5.1日期推算
⚽5.2 矩形
⚽5.3人员信息
6.1动态顺序表
6.2由圆派生出圆柱
6.3虚函数--交通工具
【问题描述】
编写一个程序,先读入一个正整数 N,对其做质因数分解。
例如:90 = 2 * 3 * 3 * 5
【问题分析】
其实不需要判断除数是否为质数:除数从2开始增加,能整除就整除,并继续用2除,直到2不能整除,除数再加1变成3,再用3去除......
【完整代码】
#include
using namespace std;
void Prime(int n);
void Prime(int n)
{
int i = 2;
while (i < n)
{
if (n % i == 0)
{
cout << i << " ";
n /= i;
}
else
i++;
}
cout << n;
}
int main()
{
int n;
cin >> n;
Prime(n);
return 0;
}
【问题描述】
编写一个程序,读入一个矩阵,输出该矩阵以第一行第一列数字为中心,顺时针旋转90度后的新矩阵,例如:
输入的矩阵为:123
456
顺时针旋转90度后输出的矩阵为:41
52
63
【样例输入】第一行为2行3列,后两行为矩阵
2 3 1 2 3 4 5 6【样例输出】
3 2 4 1 5 2 6 3
【问题分析】
先读入矩阵,从第一列最后一行向上开始输出,紧接着是第二列最后一行向上......
【完整代码】
#include
using namespace std;
int a[15][15];
int main()
{
int m, n;
cin >> m >> n;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
cout << n << " " << m << endl;
for (int i = 0; i < n - 1; i++)
for (int j = m - 1; j >= 0; j--)
{
if (j != 0)
cout << a[j][i] << " ";
else
cout << a[j][i] << endl;
}
for (int j = m - 1; j >= 0; j--)
{
if (j != 0)
cout << a[j][n - 1] << " ";
else
cout << a[j][n - 1];
}
return 0;
}
【问题描述】
编写一个程序,输入一个正整数n和字符串A,对字符串A作如下处理:
去掉重复的字符
去掉所有非字母非数字的字符
将字母大小写互换
按照字符的ASCII码从大到小排序
最后在同一行里输出n个处理后的字符串A
【样例输入】
2 abcd123【样例输出】
DCBA321DCBA321
【问题分析】
本题对字符串的处理顺序非常重要。
- 如果一来就对原字符串去掉重复字符,实现难度很大;
- 应该先进行字母大小写互换,再进行排序;(同一个字母的大小写ASCII码相差32)
我的顺序:
大小写转换->排序->不输出重复字符与非数字非字母字符串(排序后重复字符相邻)
注:我并未将重复字符与非数字非字母字符删去,而是在输出时进行判断。
若要删除重复字符,可参见此文4.3.3
泛型算法(sort、unique)https://blog.csdn.net/weixin_54186646/article/details/123276875?spm=1001.2014.3001.5501
【完整代码】
#include
#include
#include
using namespace std;
int main()
{
int n;
string s;
cin >> n >> s;
int l = s.length();
for (int i = 0; i < l; i++)
{
if (s[i] <= 'Z' && s[i] >= 'A')
s[i] += 32;
else if (s[i] <= 'z' && s[i] >= 'a')
s[i] -= 32;
}
sort(s.begin(), s.end(), greater());
for(int j=0;j= 'A') || (s[i] <= 'z' && s[i] >= 'a') || (s[i] <= '9' && s[i] >= '0')))
cout << s[i];
}
return 0;
}
【问题描述】
编写一个程序,读入一个以字符串表示的非负整数(串中每个字符代表一个数字),输出该正整数加一后的结果。
【问题分析】
此题用字符串存放数字,说明数字可以非常大,甚至超出long long类型的存储范围,实为一道简单的高精度加法问题。我采用通用做法,即不一定是加1。
- 倒序输入
- 逐位相加(确定位数)
- 向高位进一位(调整位数)a[i+1]+=a[i]/10;a[i]%=10;
- 倒序输出
【完整代码】
#include
#include
using namespace std;
string s;
int a[55];
int main()
{
cin >> s;
a[0] = s.length();
for (int i = 1; i <= a[0]; i++)
a[i] = s[a[0] - i] - '0';
a[1] += 1;
for (int i = 1; i <= a[0]; i++)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
if (a[a[0] + 1] > 0) a[0]++;
for (int i = a[0]; i > 0; i--)
cout << a[i];
return 0;
}
【问题描述】
回文字符串是具有回文特性的字符串:即该字符串从左向右读和从右向左读都一样,单独的字母不作为回文字符串,例如abcddcba即为一个长度为8的回文字符串。
编写一个程序,输入一个全是字母的字符串,找出字符串中最长的回文字符串,输出最长回文字符串的长度和最长的回文字符串(长度相同的输出第一个),若无回文字符串,只输出0。
【样例输入】
aAabccbaABcdcBA【样例输出】
8 AabccbaA
【问题分析】
问题1:需要判断一个字符串是否为回文序列
可用两指针指向序列头尾,并移动指针同时向中间靠拢,判断指向的两字符是否相等,直到两指针相遇(奇数个字符)或相差一个位置(偶数个字符)。递归实现
问题2:需要在一个大的字符串中找到最长的一段回文序列
可挨个遍历并截取小段字符判断是否为回文序列(若是,则记录字符串长度),若有更长的回文序列,则进行更新,直到将整个字符串遍历完。
【完整代码】
#include
#include
using namespace std;
typedef struct
{
int max;//当前字符长度
int a;//当前序列第一个字符
int b;//当前序列最后一个字符
}H;
/*递归*/
bool Huiwen(string s, int low, int high)
{
if (s[low] != s[high])
return false;
if(low==high||low==high-1)
return true;
return Huiwen(s, low + 1,high - 1);
}
int main()
{
string s;
cin >> s;
int l = s.length();
H h;
h.max = 0;
h.a = 0;
h.b = l - 1;
//挨个截取出子字符串
for (int i = 0; i < l; i++)
{
for (int j = l - 1; j > i; j--)
{
bool ret = Huiwen(s, i, j);
//是回文字符串且比记录的字符串长度还要长,则记录此字符串
if (ret == true && (j - i + 1) > h.max)
{
h.max = j - i + 1;
h.a = i;
h.b = j;
}
}
}
if (h.max != 0)
{
cout << h.max << endl;
for (int i = h.a; i <= h.b; i++)
cout << s[i];
}
else
cout << h.max;
return 0;
}
【问题描述】
建立一个类,在类中使用一个方法完成摄氏华氏温度的转换。假如用C表示摄氏温度,F表示华氏温度,则有:F=C*9/5+32。输入一整数表示摄氏温度,根据该公式编程求对应的华氏温度,结果小数点后保留一位有效数字。
【问题分析】
考察类的相关语法,注意C++中采用cout输出时的小数点保留问题
头文件#include
cout <
代表保留一位小数
【完整代码】
#include
#include
using namespace std;
class Tep
{
public:
int c;
double f;
void convert()
{
f = double(c) * 9 / 5 + 32;
}
};
int main()
{
Tep t;
cin >> t.c;
t.convert();
cout <
【问题描述】
用类和对象实现简易的计算器:读入两个整数运算数(data1和data2)及一个运算符(op),计算表达式data1 op data2的值,
其中op可以是+,-,*,/。
【问题分析】
注意:控制台输出运算结果,作除法运算时,若能够整除,则输出为整数,否则输出结果小数点后应保留两位有效数字。
【完整代码】
#include
#include
#include
using namespace std;
class Cal
{
public:
int data1, data2;
string s;
void calculate()
{
if (s == "+")
cout << data1 + data2;
else if (s == "-")
cout << data1 - data2;
else if (s == "*")
cout << data1 * data2;
else if (s == "/")
{
if (data1 % data2 == 0)
cout << data1 / data2;
else
cout << fixed << setprecision(2) << double(data1) / double(data2);
}
}
};
int main()
{
Cal c;
cin >> c.data1 >> c.data2 >> c.s;
c.calculate();
return 0;
}
本题专门出了一篇博客,讨论运算符重载问题。
C++运算符重载(输入输出、自增自减、累加累减)https://blog.csdn.net/weixin_54186646/article/details/123384926?spm=1001.2014.3001.5501
【问题描述】
设置一个矩形类,其属性为左上和右下两点的坐标(x1, y1)和(x2,y2)。平面上有两个矩形A和B,其位置是任意的。编程求出其相交部分(如图中阴影部分)的面积。(0≤a,b≤1000)
【输入形式】
从标准输入读取两行以空格分隔的整数,格式如下:
Ax1 Ay1 Ax2 Ay2
Bx1 By1 Bx2 By2其中(x1,y1)和(x2,y2)为矩形对角线上端点的坐标。各坐标值均为整数,取值在0至1000之间。
【输出形式】向标准输出打印一个整数,是两矩形相交部分的面积(可能为0)。
【输入样例】
0 0 2 2 1 1 3 4【输出样例】
1
【问题分析】
输入的两点可以是矩阵任一对角线上的端点,求相交面积可以先求矩形在X轴和Y轴上的交集。
矩形在X轴上的交集可以按照如下算法进行求解:
假设AX1和AX2中较大值为MAX_AX,较小值为MIN_AX;BX1和BX2中较大值为MAX_BX,较小值为MIN_BX。用MAX_AX和MAX_B中较小者减去MIN_AX和MIN_BX中的较大者,结果为正表示两矩形在X轴上的交集,若为负则表示不相交
【完整代码】
#include
#include
using namespace std;
class C
{
public:
int x1, y1, x2, y2;
int xmin = min(x1, x2);
int xmax = max(x1, x2);
int ymin = min(y1, y2);
int ymax = max(y1, y2);
};
int main()
{
C c1, c2;
int a, b, flag = 0;
cin >> c1.x1 >> c1.y1 >> c1.x2 >> c1.y2;
cin >> c2.x1 >> c2.y1 >> c2.x2 >> c2.y2;
c1.xmax = max(c1.x1, c1.x2);
c1.xmin = min(c1.x1, c1.x2);
c1.ymax = max(c1.y1, c1.y2);
c1.ymin = min(c1.y1, c1.y2);
c2.xmax = max(c2.x1, c2.x2);
c2.xmin = min(c2.x1, c2.x2);
c2.ymax = max(c2.y1, c2.y2);
c2.ymin = min(c2.y1, c2.y2);
//cout << c1.xmax;
if (min(c1.xmax, c2.xmax) > max(c1.xmin, c2.xmin))
{
a = min(c1.xmax, c2.xmax) - max(c1.xmin, c2.xmin);
flag = 1;
}
else
flag = 0;
if (min(c1.ymax, c2.ymax) > max(c1.ymin, c2.ymin))
{
b = min(c1.ymax, c2.ymax) - max(c1.ymin, c2.ymin);
flag = 1;
}
else
flag = 0;
if (flag == 1)
cout << a * b;
else
cout << 0;
return 0;
}
【问题描述】
编写一个程序,读入 N 个同学的姓名和语数外三门功课的单科成绩,对其按照一定的排序规则排序形成一张成绩表(先按总分从高到低排序,总分相同则按语文成绩由高到低排序,仍然相同则按数学成绩由高到低排序,若总分和单科成绩均相同则最后按姓名的字典序排序)。最后给定一个数字 K(K<=N) ,输出在这张排好序的成绩表中位置在第 K 位的同学的姓名和总分。
字典序举例说明:
abc > abd a > aa【输入形式】
第一行输入一个正整数 N(1<=N<=1024),代表接下来将录入 N 个学生的成绩。
接下来 N 行录入 N 条学生的成绩记录,每条记录依次为姓名,语文成绩,数学成绩,英语成绩,这四个字段以空格分隔。姓名为字符串(仅包含小写字母,不含空格,长度<=19),学生之间不会重名。三科成绩均为整数(0~100)。
最后输入一个正整数 K(1<=K<=N),代表需要在成绩表中从前往后找到的位置。
【输出形式】
在成绩表中从前往后处在第 K 位的同学的姓名和总分,中间以空格分隔。
【样例输入】
4 lily 90 100 88 jack 87 79 95 hanz 90 89 71 david 90 89 71 4【样例输出】
hanz 250
【问题分析】
这是一个排序问题,而且需要对一个人的多个属性都进行排序,属性之间也存在优先级,所以我们可以将一个人用结构体表示,姓名、语文、数学、英语、总分为其四个属性。
在C++的题目里,我们通常采用sort()进行排序,但对于结构体的排序,需要我们自定义函数cmp来实现。(关于泛型算法的自定义,我后面也会出篇文章的,介绍自定义函数与lambda表达式,这里是关于泛型算法的第一篇文章)
STL中的sort()是结合了快速排序与插入排序的一种排序,目前是STL中最好的排序,但最近有一种新的算法应该应用在了Java里,比这种排序更好。
4.3.1sort()https://blog.csdn.net/weixin_54186646/article/details/123276875?spm=1001.2014.3001.5501
【完整代码】
#include
#include
#include
const int N = 1030;
using namespace std;
class Grade
{
public:
int C, M, E;
string s;
int sum;
};
//return true就不排序;false就要排序
//string中的>、<按字典序排序
bool cmp(const Grade& g1, const Grade& g2)
{
if (g1.sum > g2.sum)
return true;
else if (g1.sum == g2.sum && g1.C > g2.C)
return true;
else if (g1.sum == g2.sum && g1.C == g2.C && g1.M > g2.M)
return true;
else if (g1.sum == g2.sum && g1.C == g2.C && g1.M == g2.M && g1.s< g2.s)
return true;
else
return false;
}
int main()
{
int n,k;
cin >> n;
Grade g[N];
for (int i = 0; i < n; i++)
{
cin >> g[i].s >> g[i].C >> g[i].M >> g[i].E;
g[i].sum = g[i].C + g[i].M + g[i].E;
}
sort(g , g + n,cmp);
cin >> k;
cout << g[k-1].s << " " << g[k-1].sum;
return 0;
}
本题专门出了一篇博客,讨论动态二维数组类问题。
动态二维数组类(C++ Vector)https://blog.csdn.net/weixin_54186646/article/details/123442733?spm=1001.2014.3001.5501
【问题描述】
设计一个类用于存放日期,并向后推算指定日期经过n天后的具体日期。
【问题分析】
来说说我的想法:
- 首先计算从今天到1年1月1号的天数n1(把相应年、月、日的天数相加,用循环实现)
- 加上n天
- 再计算n2=n+n1天后的日期(看n2够减多少年,一年不够减,再减月,一个月不够减,再减天数)
【完整代码】
#include
#include
using namespace std;
class Date
{
public:
static int a[2][12];
static int b[2];
int y0;
int m0;
int d0;
//这里的构造函数不必要,只是练练而已
Date(int y = 0, int m = 0, int d = 0)
{
y0 = y;
m0 = m;
d0 = d;
}
int judge(int a);
friend istream& operator>>(istream& is, Date& d);
friend ostream& operator<<(ostream& os, Date& d);
int days_1(Date& d);
void days_2(int sum, Date& d);
};
/*b[0]:非闰年天数 b[1]:闰年天数*/
int Date::b[2] = { 365,366 };
/*a[0][12]:非闰年的每月天数 a[1][12]闰年的每月天数*/
int Date::a[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
/*是否是闰年,是则返回1,不是则返回0*/
int Date:: judge(int a)
{
if ((a % 4 == 0 && a % 100 != 0) || a % 400 == 0)
return 1;
else
return 0;
}
/*按字符串读入,并分别按int型保存年月日*/
istream& operator>>(istream& is, Date& d)
{
string s;
is >> s;
d.y0 = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0');
d.m0 = (s[4] - '0') * 10 + (s[5] - '0');
d.d0 = (s[6] - '0') * 10 + (s[7] - '0');
return is;
}
/*主要是添0,与超出限制*/
ostream& operator<<(ostream& os, Date& d)
{
if (d.y0 < 1000)
{
os << "0" << d.y0;
if (d.m0 < 10)
{
os << "0" << d.m0;
if (d.d0 < 10)
os << "0" << d.d0 ;
else
os << d.d0;
}
else
{
os << d.m0;
if (d.d0 < 10)
os << "0" << d.d0;
else
os << d.d0;
}
}
else if (d.y0 >= 1000 && d.y0 <= 9999)
{
os << d.y0;
if (d.m0 < 10)
{
os << "0" << d.m0;
if (d.d0 < 10)
os << "0" << d.d0 ;
else
os << d.d0 ;
}
else
{
os << d.m0;
if (d.d0 < 10)
os << "0" << d.d0 ;
else
os << d.d0 ;
}
}
else
os << "out of limitation!";
return os;
}
/*计算从1年1月1日到今天有多少天,保存在sum里*/
int Date::days_1(Date &d)
{
int sum = 0;
//从(今年-1)到1年,把每年的天数相加(今年还没满)
for (int i = d.y0-1; i > 0; i--)
{
sum += b[judge(i)];
}
//从(本月-1)到1月,把每月的天数相加(本月还没满)
for (int j = d.m0-1; j >0; j--)
{
sum += a[judge(d.y0)][j - 1];
}
//加入当月的天数
sum += d.d0 -1;
return sum;
}
/*输入n(n大于0),则返回从1年1月1日(包括当天)开始经过了n天后的日期(不包括当天)*/
void Date:: days_2(int sum, Date &d)
{
//sum够减多少年的
for (d.y0 = 1; sum >= b[judge(d.y0)]; d.y0++)
{
sum -= b[judge(d.y0)];
}
//一年已经不够减了,再来减月
for (d.m0 = 0; sum >= a[judge(d.y0)][d.m0]; d.m0++)
{
sum -= a[judge(d.y0)][d.m0];
}
//一月已经不够减了,剩下的天数+1就是几号了,此时又要加一个月
d.m0++;
d.d0 = sum + 1;
}
int main()
{
Date d1;
cin >> d1;
int n;
cin >> n;
n += d1.days_1(d1);
//此时的n为从1年1月1日到再经过原来的n日的总共天数
d1.days_2(n, d1);
cout << d1;
}
【问题描述】
设计一个Rectangle类。要求:
(1)包含两个成员变量m_length和m_width,其默认值为1。
(2)包含成员函数Perimeter()计算长方形的周长,Area()计算长方形面积。
(3)包含成员函数SetWidth()和GetWidth()用来设置和得到m_width的值,SetLength()和GetLength()用来设置和得到m_length的值。SetRange()函数应验证m_length和m_width均为0.0到20.0之间的浮点数。
(4)编写主函数,测试Rectangle类。
【样例输入】
4 5【样例输出】
Length: 4 Width: 5 length and width are both in 0.0 - 20.0 Perimeter: 18 Area: 20
【完整代码】
#include
using namespace std;
class Rectangle
{
public:
double m_length,m_width;
double p, a;
Rectangle(double l=1, double w=1)
{
m_length = l;
m_width = w;
}
Rectangle& Perimeter();
Rectangle& Area();
Rectangle& SetWidth(double w);
void GetWidth(Rectangle& r);
Rectangle& SetLength(double l);
void GetLength(Rectangle& r);
void SetRange(Rectangle& r);
};
Rectangle& Rectangle::Perimeter()
{
p = 2 * (m_length + m_width);
cout << "Perimeter: " << p << endl;
return *this;
}
Rectangle& Rectangle::Area()
{
a = m_length * m_width;
cout << "Area: " << a;
return *this;
}
void GetWidth(Rectangle &r)
{
double w;
cin >> w;
r.SetWidth(w);
}
Rectangle& Rectangle::SetWidth(double w)
{
m_width = w;
cout << "Width: " << m_width << endl;
return *this;
}
void GetLength( Rectangle& r)
{
double l;
cin >> l;
r.SetLength(l);
}
Rectangle& Rectangle::SetLength(double l)
{
m_length = l;
cout << "Length: " << m_length<<" ";
return *this;
}
void SetRange(Rectangle& r)
{
if (r.m_length <= 20 && r.m_width <= 20 && r.m_length > 0 && r.m_width > 0)
cout << "length and width are both in 0.0 - 20.0"< 20 && r.m_length > 0)
cout << "width is not in 0.0 - 20.0" << endl;
else if (r.m_length > 20 && r.m_width <= 20 && r.m_width > 0)
cout << "length is not in 0.0 - 20.0" << endl;
else
cout << "length and width are not in 0.0 - 20.0"<
【问题描述】
编写一个Person类,包括:
1、普通数据成员:姓名,性别,年龄。
2、三个构造函数:无参数构造函数,有参数构造函数(参数:姓名的指针,年龄,性别),拷贝构造函数。
编写main()函数,分别调用三种构造函数,创建三个对象P1、P2、P3,其中P3的创建是用P2通过深拷贝复制得到的。
【问题分析】
三种构造函数
1.无参构造函数
person(){}
2.有参构造函数
person(int a){}
3.拷贝构造函数
person(const person &p){}
三种调用方法
1.括号法
person p1;//默认构造函数调用
person p2(10);//有参构造函数
person p3(p2);//拷贝函数构造2.显示法
person p4=person(10); //有参构造
person p5=person(p3);//拷贝构造
注意: person(10)为匿名对象,当前行执行结束后,系统会立即回收匿名对象,不要利用拷贝构造函数初始化匿名对象 ,会被认为无参构造函数3.隐式转换法
person p6=10;//相当于person p6=person(10)
person p7=p6;
【完整代码】
#include
#include
using namespace std;
class Person
{
public:
string name,s;
int g;
int age;
Person()
{
string n;
int g0;
int a;
cin >> n >> g0 >> a;
cout << "Parameterless constructor" << endl;
cout << "Information:" << endl;
if (g0 == 1)
s = "female";
else
s = "male";
name = n;
g = g0;
age = a;
cout << "Name: " << name << " Sex: " << s << " Age: " << age << endl;
}
Person(string n,int g0,int a)
{
cout << "Parameter constructor" << endl;
cout << "Information:" << endl;
if (g0 == 1)
s = "female";
else
s = "male";
name = n;
g = g0;
age = a;
cout << "Name: " << name << " Sex: " << s << " Age: " << age << endl;
}
Person(const Person& p)
{
cout << "Copy constructor" << endl;
cout << "Information:" << endl;
cout << "Name: " << p.name << " Sex: " <> n >> g >> a;
Person p2(n, g, a);
Person p3(p2);
return 0;
}
【问题描述】
设计动态顺序表类,实现表内数据的自动排序。初始化时输入5个整数,使表内数据完成排序并输出。之后在表的最后插入数字8,再次排序并输出。最后通过拷贝构造函数得到另一个相同的表并输出,并使用析构函数释放内存。
【问题分析】
考察构造函数与析构函数。
【完整代码】
#include
#include
#include
using namespace std;
class List
{
public:
vector v;
void Input()
{
int x;
for (int i = 0; i < 5; i++)
{
cin >> x;
v.push_back(x);
}
}
void Sort()
{
sort(v.begin(), v.end());
}
void insert()
{
v.push_back(8);
Sort();
}
void show()
{
for (auto it = v.begin(); it != v.end(); it++)
cout << *it << " ";
}
~List()
{
vector(v).swap(v);
}
List(const List &l)
{
v = l.v;
}
List()
{}
};
int main()
{
List l;
l.Input();
l.Sort();
l.show();
cout << endl;
l.insert();
l.Sort();
l.show();
cout << endl;
List l1(l);
l1.show();
return 0;
}
【问题描述】
定义一个Circle圆形类,在此基础上派生出Cylinder圆柱体类。要求在主程序中输入圆的半径后输出对应半径的圆的面积(area),再在输入圆柱的高之后输出对应圆底半径和高的圆柱体表面积(area)和体积(volume)。
【问题分析】
考察有参构造函数、类的继承
我在刚开始时,把输入(cin>>)写在了构造函数里面,这时出现了一个问题:子类虽然可以继承父类的属性,但似乎不能继承父类已经给半径r赋好的值,这就导致子类的r没有被赋值。
于是,我们还是应该在主函数main里定义半径r与圆柱高h,通过有参构造函数,将r与h分别传递给Circle类与Cylinder类。
【完整代码】
#include
using namespace std;
const double pi = 3.14;
class Circle
{
public:
double r;
Circle(double x) :r(x) {}
double Area() { return r * r * pi; }
};
class Cylinder :public Circle
{
public:
double h;
Cylinder(double x, double y) :Circle(x), h(y) { }
double S() { return 2 * r * r * pi + h * 2 * pi * r; }
double V() { return h *r * r * pi; }
};
int main()
{
double r, h;
cout << "Please enter the radius of the circle:";
cin >> r;
cout << "Please enter the height of the cylinder:";
cin >> h;
Circle c(r);
Cylinder C(r,h);
cout << "The area of the circle is:" << c.Area() << endl;
cout << "The area of the cylinder is:" << C.S() << endl;
cout << "The volumn of the cylinder is:" << C.V();
return 0;
}
【问题描述】
定义一个交通工具类vehicle,其具有三种基本属性:速度、轮子数量和重量。将它作为基类派生校车类car,卡车类truck和轮船类boat,定义类并定义虚函数来显示三种交通工具的各类信息。
其中,car类需显示速度、轮子数量、重量和载客量;truck类需显示速度、轮子数量、重量和额定负载;boat类需显示速度、轮子数量、重量和轮船类别(如客轮为'k')。
【问题分析】
考察类的继承与多态(虚函数)。
虚函数
1.格式
virtual 类型 函数名(参数表)
2.作用
通过虚函数实现运行时的多态性
3.说明
- 虚函数声明只能出现在类声明中的成员函数原型声明中。
- 只有类的普通成员函数才能声明为虚函数,全局函数及静态成员函数不能声明为虚函数。
- 虚函数可以在一个或多个派生类中被重复定义,因此它属于函数重载的情况。但是,这种函数重载与一般的函数重载是不同的。虚函数在派生类中重新定义时必须与基类中的原型完全相同(函数名、参数个数、参数类型、参数顺序、返回值类型)。
纯虚函数
1.来源
在多态中,通常父类中虚函数的实现毫无意义,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数。
2.格式
virtual 返回值类型 函数名 (参数类别) = 0;
3.抽象类
当类中有了纯虚函数,这个类称为抽象类。
抽象类特点:
无法实例化对象
子类必须重写抽象类中的纯虚函数,否则也属于抽象类
【完整代码】
#include
using namespace std;
class vehicle
{
public:
int speed;
int wheel;
int weight;
vehicle() {}
};
class car :public vehicle
{
public:
int people;
car()
{
speed = 80;
wheel = 4;
weight = 1000;
people = 4;
}
virtual void show()
{
cout << "car message" << endl;
cout << speed << " " << wheel << " " << weight << " " << people << endl;
}
};
class truck :public vehicle
{
public:
int load;
truck()
{
speed = 80;
wheel = 4;
weight = 2500;
load =3000;
}
virtual void show()
{
cout << "truck message" << endl;
cout << speed << " " << wheel << " " << weight << " " << load << endl;
}
};
class boat :public vehicle
{
public:
char m;
boat()
{
speed = 30;
wheel = 0;
weight = 12000;
m = 'k';
}
virtual void show()
{
cout << "boat message" << endl;
cout << speed << " " << wheel << " " << weight << " " << m;
}
};
int main()
{
car c;
c.show();
truck t;
t.show();
boat b;
b.show();
return 0;
}
谢谢你能够看到这里!