Basic CPP Homework
C++第一次上机
5-1使用引用作为函数参数
#include<iostream>
using namespace std;
void exchange(int& x,int& y)
{
int temp = x;
x = y;
y = temp;
}
int main(){
int a, b;
cin >> a >> b;
exchange(a, b);
cout << " exchange: " << a << " "<< b << endl;
return 0;
}
The meaning of Class
填空,实现部分类的特征只能读取,部分类的特征可读可写,部分类的属性只能写入
```
## 5-3显式使用this指针
填写程序中的空白,完成指定的功能。
```cpp
#include<iostream>
using namespace std;
class R{
int len,w;
public:
R(int len,int w);
int getArea();
};
R::R(int len,int w){
this->len=len;
this->w=w;
}
int R::getArea(){
return (this->len)*(this->w);
}
int main(){
R r1(2,5),r2(3,6);
cout<<"First Area is "<<r1.getArea()<<endl;
cout<<"Second Area is "<<r2.getArea()<<endl;
return 0;
}
5-4动态对象的创建
#include<bits/stdc++.h>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
}
void display(){
cout<<"i="<<i<<endl;
}
};
int main(){
A* p=new A;//动态创建对象p
p->display();
delete p;//删除对象p
p=new A(8);
p->display();
delete p;
p=new A[3];//p指向对象数组
A* q=p;
for(int i=0;i<3;i++){
q[i].display();//输出对象数组数据
}
delete[] p;//删除对象数组指针p
return 0;
}
5-5静态数据成员
#include<iostream>
using namespace std;
class Point{
double x,y;
static int count;//定义静态变量
public:
Point(double a=0,double b=0):x(a),y(b){
count++;
}
~Point(){
count--;
}
void show(){
cout<<"the number of Point is "<<count<<endl;
}
};
int Point::count=0;
int main(){
Point p1;
Point* p=new Point(1,2);
p->show();
delete p;
p1.show();
return 0;
}
5-6点类的定义和使用
已知平面上的一点由其横纵坐标来标识。本题要求按照已给代码和注释完成一个基本的“点”类的定义(坐标均取整型数值)。并通过主函数中的点类对象完成一些简单操作,分析程序运行结果,将答案写在对应的空格中。
#include <iostream>
using namespace std;
class Point{
private://访问权限设置,私有权限
int x;//横坐标
int y;//纵坐标
//访问权限设置,公有权限
public:
//以下为构造函数,用参数a,b分别为横纵坐标进行初始化
Point(int a,int b){
this->x=a;
this->y=b;
}
//以下为拷贝构造函数,借用对象a_point完成初始化
Point(const Point& a_point){
x=a_point.x;
y=a_point.y;
}
//以下为析构函数
~Point(){
cout<<"Deconstructed Point";
print();
}
//以下为输出点的信息的函数,要求在一行中输出点的坐标信息,形如:(横坐标,纵坐标)
void print(){
cout<<"x="<<this->x<<",y="<<this->y<<endl;
}
};
int main(){
Point b_point(0,0);
b_point.print();
int a,b;
cin>>a>>b;//从标准输入流中提取数值给a,b
Point c_point(a,b);
c_point.print();
return 0;//主函数的返回语句
}
5-7排队队吃果
幼稚园阿姨发糖,先到先得。请查询资料,使用队列(queue)容器模拟幼稚园小朋友Jack、Mary、Tom、Angela和Alex依次到达(入队)并依次出队领糖的过程。
#include <iostream>
#include<queue>
using namespace std;
int main(){
queue<string> q;
q.push("Jack");
q.push("Mary");
q.push("Tom");
q.push("Angela");
q.push("Alex");
while (!q.empty()){
string s = q.front();
q.pop();
cout << s<< " get candy." << endl;
}
return 0;
}
5-8 new/delete
#include<bits/stdc++.h>
// using namespace std;
int main(){
int* pi=new int(10);
//new 一个int对象,初始值为10
std::cout<<"*pi="<<*pi<<std::endl;
*pi=20;//通过指针改变变量的值
std::cout<<"*pi = "<<*pi<<std::endl;
delete pi;//释放int对象
return 0;
}
6-1 平面矩形 - 《C++编程基础及应用》- 习题13-4
分数 20
作者 海洋饼干叔叔
单位 重庆大学
在一个平面内,由左上角(top left)顶点坐标结合右下角(bottom right)顶点坐标即可确定一个平面矩形。请设计Rect和Point类,使其可以被下述代码所利用,并产生期望的输出。
裁判测试程序样例:
//Project - Rect
#include <iostream>
#include <cmath>
using namespace std;
//定义Point类
//定义Rect类
int main() {
auto rt = Rect(Point(1,6),Point(7,8));
printf("Vertices of rectangle rt:\n");
printf("(%d,%d)-----------------------(%d,%d)\n",
rt.tl.x,rt.tl.y,rt.topRight().x,rt.topRight().y);
printf("(%d,%d)-----------------------(%d,%d)\n",
rt.bottomLeft().x,rt.bottomLeft().y,rt.br.x,rt.br.y);
printf("Size information of rectangle rt:\n");
printf("width - %d height - %d\n",rt.width(),rt.height());
printf("area - %d diagonal legnth - %.2f",rt.area(),rt.diagonalLength());
return 0;
}
输入样例:
输出样例:
Vertices of rectangle rt:
(1,6)-----------------------(7,6)
(1,8)-----------------------(7,8)
Size information of rectangle rt:
width - 6 height - 2
area - 12 diagonal legnth - 6.32
请注意:函数题只需要提交相关代码片段,不要提交完整程序。
- Point topRight()生成并返回矩形右上角顶点坐标;
- Point bottomLeft()生成并返回矩形左下角顶点的坐标;
- 属性Point tl表示左上角顶点坐标, br表示右下角顶点坐标;
- int width(), int height()分别计算并返回矩形的宽,高;
- double diagonalLength()计算并返回矩形的对角线长度,使用勾股定理进行计算。
Code
240401
#include <iostream>
#include <cmath>
using namespace std;
class Point{
public:
int x,y;
Point(const int& _x,const int& _y):x(_x),y(_y){}
~Point(){}
};
class Rect{
public:
Point tl,br;
Rect(const Point& _p1,const Point& _p2):tl(_p1),br(_p2){}
~Rect(){}
Point topRight(){
return Point(br.x,tl.y);
}
Point bottomLeft(){
return Point(tl.x,br.y);
}
int width(){
return abs(tl.x-br.x);
}
int height(){
return abs(tl.y-br.y);
}
int area(){
return this->width()*this->height();
}
double diagonalLength(){
return sqrt(this->width()*this->width()+this->height()*this->height());
}
};
int main(){
auto rt=Rect(Point(1,6),Point(7,8));
printf("Vertices of rectangle rt:\n");
printf("(%d,%d)-----------------------(%d,%d)\n",
rt.tl.x,rt.tl.y,rt.topRight().x,rt.topRight().y);
printf("(%d,%d)-----------------------(%d,%d)\n",
rt.bottomLeft().x,rt.bottomLeft().y,rt.br.x,rt.br.y);
printf("Size information of rectangle rt:\n");
printf("width - %d height - %d\n",rt.width(),rt.height());
printf("area - %d diagonal legnth - %.2f",rt.area(),rt.diagonalLength());
return 0;
}
6-2 类的定义(学生类Student)
分数 10
作者 刘骥
单位 重庆大学
本题要求定义一个学生类Student,数据成员包含姓名name和年龄age,类的声明见给出的代码,请给出类的完整实现,并通过测试程序。
类的声明:
class Student{
private:
string name;
int age;
public:
Student(string name,int age);
string getName() const;
int getAge() const ;
void setName(string name);
void setAge(int age);
};
测试程序:
#include<iostream>
#include<string>
using namespace std;
class Student{
private:
string name;
int age;
public:
Student(string name,int age);
string getName() const;
int getAge() const ;
void setName(string name);
void setAge(int age);
};
/* 请在这里填写答案 */
int main(){
Student a("Zhang",20);
cout<<"name="<<a.getName()<<endl;
cout<<"age="<<a.getAge()<<endl;
a.setName("Li");
a.setAge(30);
cout<<"name="<<a.getName()<<endl;
cout<<"age="<<a.getAge()<<endl;
return 0;
}
测试程序的输入:
测试程序的输出:
name=Zhang
age=20
name=Li
age=30
提示
下列代码为类实现的骨架代码
Student::Student(string name,int age){
//代码
}
string Student::getName() const{
//代码
}
int Student::getAge() const{
//代码
}
void Student::setName(string name)
{
//代码
}
void Student::setAge(int age)
{
//代码
}
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
Code
240401
#include<iostream>
#include<string>
using namespace std;
class Student{
private:
string name;
int age;
public:
Student(string name,int age);
string getName() const;
int getAge() const;
void setName(string name);
void setAge(int age);
};
Student::Student(string name,int age){
this->name=name;
this->age=age;
}
string Student::getName() const{
return this->name;
}
int Student::getAge() const{
return this->age;
}
void Student::setName(string name){
this->name=name;
}
void Student::setAge(int age){
this->age=age;
}
int main(){
Student a("Zhang",20);
cout<<"name="<<a.getName()<<endl;
cout<<"age="<<a.getAge()<<endl;
a.setName("Li");
a.setAge(30);
cout<<"name="<<a.getName()<<endl;
cout<<"age="<<a.getAge()<<endl;
return 0;
}
6-3 动态输入排序
分数 20
作者 乔
单位 湖南工程学院计算机与通信学院
本题要求实现一个函数input,能够输入n个整数。
裁判测试程序样例:
/* 请在这里填写答案 */
//实现input函数
void sort(int a[], int n){
int i,j;
for(i=0;i<n-1;i++){
int min = i;
for(j=i+1;j<n;j++){
if(a[min]>a[j]) min = j;
}
int t = a[i]; a[i] = a[min]; a[min] = t;
}
}
int main(){
int *a;
int n;
cin>>n; //输入数据的数量
input(a,n); //输入n个整数
sort(a,n); //将数组a按从小到大排序
for(int i=0;i<n;i++)
cout<<a[i]<<" "; //按顺序输出
if(a!=NULL)
delete []a;
return 0;
}
输入样例:
在这里给出一组输入。例如:
5
10 9 8 7 6
输出样例:
在这里给出相应的输出。例如:
6 7 8 9 10
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
Code
240401
#include<bits/stdc++.h>
using namespace std;
void input(int*& a,int& n){
a=new int[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
}
void sort(int a[],int n){
int i,j;
for(i=0;i<n-1;i++){
int min=i;
for(j=i+1;j<n;j++){
if(a[min]>a[j]) min=j;
}
int t=a[i]; a[i]=a[min]; a[min]=t;
}
}
int main(){
int* a;
int n;
cin>>n; //输入数据的数量
input(a,n); //输入n个整数
sort(a,n); //将数组a按从小到大排序
for(int i=0;i<n;i++)
cout<<a[i]<<" "; //按顺序输出
if(a!=NULL)
delete[]a;
return 0;
}
6-4 客户机类
分数 10
作者 杨军
单位 四川师范大学
实现客户机(Client)类。定义字符型静态数据成员ServerName,保存其服务器名称;整型静态数据成员ClientNum,记录已定义的客户机数量;定义静态函数ChangeServerName()改变服务器名称。完成程序,使得提供的测试程序可以运行并得到要求的结果。
函数接口定义:
根据要求实现类代码
裁判测试程序样例:
/*在这里完成类代码*/
在这里给出函数被调用进行测试的例子。例如:
int main(){
Client::show();
Client c1;
Client::show();
Client::changeServerName('B');
Client::show();
}
输入样例:
在这里给出一组输入。例如:
无
输出样例:
在这里给出相应的输出。例如:
server name:A
num of clients:0
server name:A
num of clients:1
server name:B
num of clients:1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
Code
240401
这题纯纯sb,裁判机居然不自带头文件。
#include<bits/stdc++.h>
using namespace std;
class Client{
public:
static int ClientNum;
static char ServerName;
Client(){
ClientNum++;
}
static void show(){
cout<<"server name:"<<ServerName<<"\n";
cout<<"num of clients:"<<ClientNum<<"\n";
}
static void changeServerName(char ch){
ServerName=ch;
}
};
int Client::ClientNum=0;
char Client::ServerName='A';
6-5 日复一日 - 《C++编程基础及应用》- 习题13-2
分数 20
作者 海洋饼干叔叔
单位 重庆大学
设计符合下述要求的日期类(Date),使得下述代码可以正常运行。
- 拥有数据成员year、month和day,分别存储年、月、日;
- 构造函数接受年、月、日参数并初始化全部数据成员;
- 公有成员函数toText()返回一个string对象,该字符串为该日期对象的文字表达,比如“2022-5-20”;
- 公有成员函数nextDay()返回一个Date对象,表示该日期的后一天;
- 公有成员函数prevDay()返回一个Date对象,表示该日期的前一天。
裁判测试程序样例:
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
//请在此处定义Date类
int main()
{
int year=2000,month=1,day=1;
cin >> year >> month >> day;
Date d(year,month,day);
cout << "Date: " << d.toText() << ", Next Day: " << d.nextDay().toText()
<< ", Prev Day: " << d.prevDay().toText();
return 0;
}
输入样例:
2000 3 1
说明:依次是年-月-日。
输出样例:
Date: 2000-3-1, Next Day: 2000-3-2, Prev Day: 2000-2-29
提示:需要注意闰年,闰年2月有29天,平年28天。 闰年判定函数:
bool isLeapYear(int year){
//四年一闰,百年不闰,四百年又闰
if (year%400==0)
return true;
else if (year%100==0)
return false;
else if (year%4==0)
return true;
else
return false;
}
请注意:函数题只需要提交相关代码片段,不要提交完整程序。
Code
240401
class Date{
private:
int y,m,d;
bool isLeapYear(int year){
if(year%4!=0) return false;
if(year%400==0) return true;
if(year%100==0) return false;
return true;
}
public:
Date(const int& _y,const int& _m,const int& _d):y(_y),m(_m),d(_d){}
string toText(){
return to_string(this->y)+"-"+to_string(this->m)+"-"+to_string(this->d);
}
Date(const Date& other){
this->y=other.y;
this->m=other.m;
this->d=other.d;
}
Date nextDay(){
Date res(*this);
res.d++;
if(res.m==2){
if(isLeapYear(res.y)){
if(res.d>29){
res.d-=29;
res.m++;
}
}else{
if(res.d>28){
res.d-=28;
res.m++;
}
}
}else if(res.m==1 || res.m==3 || res.m==5 || res.m==7 || res.m==8 || res.m==10 || res.m==12){
if(res.d>31){
res.d-=31;
res.m++;
}
}else{
if(res.d>30){
res.d-=30;
res.m++;
}
}
if(res.m>12){
res.m-=12;
res.y++;
}
return res;
}
Date prevDay(){
Date res(*this);
res.d--;
if(res.d>0) return res;
res.m--;
if(res.m==0) return Date(this->y-1,12,31);
if(res.m==2){
if(isLeapYear(res.y)) res.d=29;
else res.d=28;
return res;
}if(res.m==1 || res.m==3 || res.m==5 || res.m==7 || res.m==8 || res.m==10 || res.m==12){
res.d=31;
}else{
res.d=30;
}
return res;
}
};
6-6 凸N边形的面积 - 《C++编程基础及应用》- 习题13-5
分数 20
作者 海洋饼干叔叔
单位 重庆大学
请设计符合下述要求的Point及Polygon类,使得程序可以正常运行。
平面内的N边形可以用N个顶点坐标来表示。请设计Point类表示一个顶点。请设计Polygon类表示一个N边形(N≥3):
- 私有数据成员pts类型为Point*,用于指向多边形的N个动态顶点对象;
- 构造函数接受一个整数n作为参数,n为多边形边数/点数;构造函数中需要动态分配顶点对象数组pts;
- setVertice(int i, const Point& p)成员函数用于设置第i个顶点的坐标;
- getVertice(i)成员函数获取并返回多边形的第i个顶点;
- 在析构函数中释放动态顶点对象;
- 公有函数getArea()计算并返回该多边形的面积(假设多边形为凸多边形,计算方法参考练习11-5)。
练习11-5中关于凸六边形面积计算的描述: 如图所示,当六边形为凸六边形时,可以将其拆分成四个三角形,利用海伦-秦九韶公式分别计算三角形的面积并相加,即得凸六边形的面积。
![image.png](https://images.ptausercontent.com/e489faf8-8b62-44b7-b923-ba399e3a4c63.png)
裁判测试程序样例:
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
//请在此处定义Point类及Polygon类
int main()
{
Polygon poly1(6);
poly1.setVertice(0,Point(0,0));
poly1.setVertice(1,Point(33.2,30));
poly1.setVertice(2,Point(61.2,0));
poly1.setVertice(3,Point(61,-29.1));
poly1.setVertice(4,Point(20,-57.7));
poly1.setVertice(5,Point(0,-33.2));
printf("Vertex 3 of poly 1: (%.1f, %.1f)\n",poly1.getVertice(3).x,poly1.getVertice(3).y);
printf("Area of polygon 1: %.1f\n",poly1.getArea());
Polygon poly2(4);
poly2.setVertice(0,Point(0,0));
poly2.setVertice(1,Point(33.2,0.7));
poly2.setVertice(2,Point(20.3,-22));
poly2.setVertice(3,Point(5.1,-19.7));
printf("Vertex 2 of poly 2: (%.1f, %.1f)\n",poly2.getVertice(2).x,poly2.getVertice(2).y);
printf("Area of polygon 2: %.1f\n",poly2.getArea());
return 0;
}
输入样例:
输出样例:
Vertex 3 of poly 1: (61.0, -29.1)
Area of polygon 1: 3609.3
Vertex 2 of poly 2: (20.3, -22.0)
Area of polygon 2: 516.2
请注意:函数题只需要提交相关代码片段,不要提交完整程序。
Code
240401
class Point{
public:
double x,y;
Point():x(0.0),y(0.0){}
Point(const double& _x,const double& _y):x(_x),y(_y){}
Point operator-(const Point& other) const{
return Point(this->x-other.x,this->y-other.y);
}
};
class Polygon{
private:
Point* p;
int size;
double CrossProduct(const Point& p1,const Point& p2,const Point& root){
Point vec1=p1-root;
Point vec2=p2-root;
return vec1.x*vec2.y-vec2.x*vec1.y;
}
public:
Polygon(const int& _size):size(_size){
p=new Point[size];
}
void setVertice(int n,const Point& point){
p[n]=point;
}
Point getVertice(int n){
return p[n];
}
double getArea(){
double area=0;
for(int i=2;i<size;i++){
area+=CrossProduct(p[i],p[i-1],p[0]);
}
return area/2.0;
}
};
CPP第二次上机
5-1 知识点2:普通构造函数及初始化
- 对象的初始化和清理也是两个非常重要的安全问题
- 一个对象或者变量没有初始状态,对其使用后果是未知
- 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
- c++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
构造函数:类名(输入参数){函数体}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
- 构造函数可以使用“:”进行初始化
成员变量通过构造函数初始化:
- 在实现构造函数时,还可以通过“:”运算符,在构造函数后面初始化成员变量,这种方式称为列表初始化,其格式如下所示:
类名(输入参数列表): 成员变量1(输入参数1), 成员变量的2(输入参数2),…, 成员变量n(输入参数n) { 函数体 }
构造函数的调用顺序:
- 类的成员变量也可以是属于别的类的对象
- 当创建对象a中含有属于别的类对象b时,先执行成员对象b的构造函数,再执行a的构造函数
例:
补全下面两个类,一个Birth
,一个Student
,后者的成员变量中含有前者的对象
#include<iostream>
using namespace std;
class Birth{
public:
Birth(int y,int m,int d):_year(y),_month(m),_day(d){
cout<<"Birth类构造函数"<<endl;
}
void show(){ cout<<_year<<"-"<<_month<<"-"<<_day<<endl; }
private:
int _year;
int _month;
int _day;
};
class Student{
public:
Student(string name,int id,int y,int m,int d):birth(y,m,d){
cout<<"Student类构造函数"<<endl;
_name=name;
_id=id;
}
void show(){
cout<<_name<<_id<<endl;
birth.show();
}
private:
string _name;
int _id;
Birth birth;
};
int main(){
Student stu("物联",10002,2022,9,1);
stu.show();
return 0;//最后输出结果中,先输出“Birth类构造函数”,再输出“Student类构造函数”
}
5-2 知识点3:拷贝构造函数及构造函数的重载
拷贝构造函数:构造函数名称(const 类名 &对象名) { 函数体 }
- 拷贝构造函数是一种特殊的构造函数,它具有构造函数的所有特性,并且使用本类对象的引用作为形参,其作用是使用一个已经存在的对象初始化该类的另一个对象。
- 在定义拷贝构造函数时,为了使引用的对象不被修改,通常使用const修饰引用的对象。
构造函数重载:类名(不同的输入参数){函数体}
- 当定义具有默认参数的重载构造函数时,要防止调用的二义性。
例:
补充Birth类与Student类的拷贝构造函数,并对Student类的构造函数重载
#include<iostream>
using namespace std;
class Birth{
public:
Birth(int year,int month,int day):_year(year),_month(month),_day(day){
cout<<"Birth类构造函数"<<endl;
}
Birth(const Birth& other):_year(other._year),_month(other._month),_day(other._day){//拷贝构造函数
cout<<"Birth类拷贝构造函数"<<endl;
}
void show(){ cout<<_year<<"-"<<_month<<"-"<<_day<<endl; }
private:
int _year;
int _month;
int _day;
};
class Student{
public:
Student(string name,int id,int year,int month,int day):birth(year,month,day){
cout<<"Student类构造函数"<<endl;
_name=name;
_id=id;
}
//重载构造函数,不需要输入生日,默认生日1990-1-1
Student(string name,int id):birth(Birth(1990,1,1)){
cout<<"Student类重载构造函数"<<endl;
_name=name;
_id=id;
}
//拷贝构造函数,注意这里的birth对象初始化,需要调用Birth类的拷贝构造函数
Student(const Student& other):birth(other.birth){
cout<<"Student类拷贝构造函数"<<endl;
_name=other._name;
_id=other._id;
}
void show(){
cout<<_name<<_id<<endl;
birth.show();
}
private:
string _name;
int _id;
Birth birth;
};
int main(){
Student stu("物联22",10002,2000,1,1);
Student stu2("物联222",10001);
Student stu3(stu);
return 0;
}
5-3 知识点4:析构函数
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
析构函数语法: ~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号 ~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
- 析构函数没有返回值,不能在析构函数名称前添加任何返回值类型。在析构函数内部,也不能通过return返回任何值。
析构函数的调用顺序
- 析构函数的调用顺序与构造函数的调用顺序是相反的。在构造对象和析构对象时,C++遵循的原则是:先构造的后析构,后构造的先析构。
什么时候调用析构函数
- 在一个函数中定义了一个对象,当函数调用结束时,对象应当被释放,对象释放之前,编译器会调用析构函数释放资源。
- static修饰的对象和全局对象,只有在程序结束时才会调用析构函数。
- new运算符创建的对象,在调用delete释放对象时,编译器会调用析构函数释放资源。
例:为Student类与Birth类加入析构函数,并观察Birth类与Student类析构函数调用顺序
#include<iostream>
using namespace std;
class Birth{
public:
Birth(int year,int month,int day):_year(year),_month(month),_day(day){
//cout<<"Birth类构造函数"<<endl;
}
Birth(const Birth& another):_year(another._year),_month(another._month),_day(another._day){
//cout<<"Birth类拷贝构造函数"<<endl;
}
~Birth(){
cout<<"Birth类析构函数"<<endl;
}
void show(){ cout<<_year<<"-"<<_month<<"-"<<_day<<endl; }
private:
int _year; int _month; int _day;
};
class Student{
public:
Student(string name,int id,int year,int month,int day):birth(year,month,day){
//cout<<"Student类构造函数"<<endl;
_name=name;
_id=id;
}
Student(string name,int id):birth(1900,1,1){
//cout<<"Student类重载构造函数"<<endl;
_name=name;
_id=id;
}
Student(const Student& another):birth(another.birth){
//cout<<"Student类拷贝构造函数"<<endl;
_name=another._name;
_id=another._id;
}
~Student(){
cout<<"Student类析构函数"<<_id<<endl;
}
void show(){
cout<<_name<<_id<<endl;
birth.show();
}
private:
string _name; int _id; Birth birth;
};
void f(){
//若函数中定义了对象,则在调用结束后立即调用析构函数
Student stu3("物联223",10003);
//static修饰的对象时,只有在程序结束时才会调用析构函数,位于main函数中定义的对象之后
static Student stu4("物联224",10004);
}
int main(){
Student stu("物联221",10001,2000,1,1);
Student* stu2=new Student("物联222",10002);
//new运算符创建的对象,在调用delete释放对象时立即调用析构函数
delete stu2;
f();
Student stu5("物联223",10005);
return 0;
//调用析构函数的顺序为(只填写id):,,,,
}
5-4 知识点1:const修饰的成员变量与成员函数
分数 7
作者 郑远
单位 中国民用航空飞行学院
常成员变量:
- 对于常成员变量,仅仅可以读取第一次初始化的数据,之后是不能修改的。
- 常成员变量通常使用有参数构造函数进行初始化.
- 语法
const 变量类型 变量名
常函数:
- 成员函数后加const后我们称为这个函数为常函数
- 常函数内不可以修改成员属性
- 类中定义的成员函数若与常成员函数名相同则构成重载,常成员函数只能由const修饰的对象进行访问。
- 语法:
返回值类型 函数名() const {}
常对象:
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
- 语法:
const 类名 对象名(构造函数参数)
语法:
#include<iostream>
using namespace std;
class Person{
public:
Person():m_A(1){
//const 修饰的成员变量,只有初始化时可以对其进行赋值,这里需要用初始化列表对m_A赋初值为1
//const 修饰的成员变量需要用初始化参数表进行赋值,不能在函数体中进行赋值,这句话会报错
//m_A = 0;
m_B=0;
}
//定义常成员函数ShowPerson,无返回值,无输入参数
void ShowPerson() const{
//const修饰成员函数,内部不能修改类成员,以下语句会报错
//this->m_B = 100;
//但是可以调用
cout<<this->m_B<<endl;
cout<<"重载2"<<endl;
}
//定义非常成员函数ShowPerson,与上面函数构成重载,无返回值,无输入参数
void ShowPerson(){
cout<<"重载1"<<endl;
}
void MyFunc(){
//const修饰的成员变量,除了初始化以外,在哪都不允许被修改,以下语句会报错
//mA = 10000;
//但是可以调用
cout<<this->m_A<<endl;
}
public:
const int m_A;
int m_B;
};
int main(){
const Person person1;//常量对象
Person person2;//正常对象
//正常对象调用showperson,调用的是未经const修饰的重载函数showperson
person2.ShowPerson();
person2.MyFunc();
//常对象调用showperson,调用的是经过const修饰的重载函数showperson
person1.ShowPerson();
//常对象不能调用普通成员函数,以下语句会报错
//person1.MyFunc();
return 0;
}
//程序最后输出为:
//第一行:重载1
//第二行:1
//第三行:0
//第四行:重载2
5-5 知识点2:static修饰的成员变量与成员函数
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员 静态成员分为:
- 静态成员变量 * 所有对象共享同一份数据 * 在编译阶段分配内存 *
静态成员变量定义语法
static 变量类型 变量名
* 类内声明,类外初始化,初始化语法为:变量类型 类名::变量名=初始化数(整体位于类定义的外面)
* 可以通过对象或类进行调用:对象.静态成员变量名
或类名::静态成员变量名
- 静态成员函数 * 所有对象共享同一个函数 *
静态成员函数只能访问静态成员变量 *
静态成员函数定义语法:
static 函数名(){}
* 可以通过对象或类进行调用:对象.静态函数名()
或类名::静态函数名()
#include<iostream>
using namespace std;
class Person{
public:
static int m_A; //静态成员变量
//静态成员函数func,没有输入
static void func(){
cout<<"func调用"<<endl;
m_A=100;
//m_B = 100; //静态成员函数不可以访问非静态成员变量,这句话会报错
}
private:
static void func2()//静态成员函数也是有访问权限的
{
cout<<"func2调用"<<endl;
}
static int m_B; //静态成员变量也是有访问权限的
};
//静态成员变量初始化,私有对象可以在外面初始化但访问不了
int Person::m_A=10;//初始化m_A
int Person::m_B=10;
int main(){
//静态成员变量两种访问方式
//1、通过对象
Person p1;
Person::m_A=100;//通过对象调用m_A
cout<<"p1.m_A = "<<p1.m_A<<endl;
Person p2;
p2.m_A=200;
cout<<"p1.m_A = "<<p1.m_A<<endl; //共享同一份数据
cout<<"p2.m_A = "<<p2.m_A<<endl;
//2、通过类名
cout<<"m_A = " << Person::m_A << endl;//通过类名调用m_A
//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
//静态成员函数两种访问方式
//1、通过对象
Person p3;
p3.func();//通过对象调用成员函数
//2、通过类名
Person::func();//通过类调用成员函数
//Person::func2(); //私有权限访问不到
return 0;
}
知识点3:friend修饰的成员变量与成员函数
生活中你的家有客厅(Public),有你的卧室(Private);客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去。但是呢,你也可以允许你的好闺蜜好基友进去。
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术;友元的目的就是让一个函数或者类 访问另一个类中私有成员
友元的关键字为 friend
友元的三种实现
- 类做友元
- 成员函数做友元
- 全局函数做友元
- friend修饰别的类
- 友元类可以声明在类中任意位置。
friend class 类名
- 声明友元类之后,友元类中的所有成员函数都是该类的友元函数,能够访问该类的所有成员。
- friend修饰成员函数
- 友元成员函数声明语法:
friend 函数返回值类型 类名::函数名();
- 注意定义的先后,建议在前面进行声明,后面进行函数的同一定义,防止出现问题。
- friend修饰类外定义的函数
- 将类外部的普通函数作为类的友元函数,在类中使用friend关键字声明该普通函数就可以实现,友元函数可以在类中任意位置声明。
- 普通函数作为友元函数的声明形式如下所示:
friend 函数返回值类型 友元函数名(形参列表)
Code
#include<iostream>
using namespace std;
class Building;
class goodGay{
public:
goodGay();
void visit();
private:
Building* building;
};
class goodGayGay{
public:
goodGayGay();
void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
void visit2();
private:
Building* building;
};
class Building{
//1.告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend goodGay;
//2.告诉编译器 goodGayGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void goodGayGay::visit();
//3.告诉编译器 printt全局函数 是 Building类的好朋友,可以访问类中的私有内容
friend void printt(Building* building);
public:
Building(){
this->m_SittingRoom="客厅";
this->m_BedRoom="卧室";
}
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
//以下为具体定义函数
goodGay::goodGay(){
building=new Building;
}
void goodGay::visit(){
cout<<"第一个好基友正在访问"<<building->m_SittingRoom<<endl;
cout<<"第一个好基友正在访问"<<building->m_BedRoom<<endl;
}
goodGayGay::goodGayGay(){
building=new Building;
}
void goodGayGay::visit(){
cout<<"第二个好基友正在访问"<<building->m_SittingRoom<<endl;
cout<<"第二个好基友正在访问"<<building->m_BedRoom<<endl;
}
void goodGayGay::visit2(){
cout<<"第二个好基友正在第二次访问"<<building->m_SittingRoom<<endl;
//cout << "第二个好基友正在第二次访问" << building->m_BedRoom << endl;
}
void printt(Building* building){
cout<<"第三个好基友正在访问: "<<building->m_SittingRoom<<endl;
cout<<"第三个好基友正在访问: "<<building->m_BedRoom<<endl;
}
void test01(){
goodGay gg;
gg.visit();
}
void test02(){
goodGayGay gg;
gg.visit();
}
void test03(){
Building b;
printt(&b);
}
int main(){
test01();//friend修饰别的类
test02();//friend修饰成员函数
test03();//friend修饰类外定义的函数
return 0;
}
6-1 猫和老鼠有多重
定义猫和老鼠:Cat与Mouse两个类,二者都有weight属性,定义二者的一个友元函数totalweight(),计算二者的重量和。
裁判测试程序样例:
#include <iostream>
using namespace std;
/* 请在这里填写答案 */
int main()
{
int w1,w2;
cin>>w1>>w2;
Cat tom(w1);
Mouse jerry(w2);
cout<<totalWeight(tom,jerry)<<endl;
}
输入样例:
100 200
输出样例:
300
Code
240415
class Cat;
class Mouse;
int totalWeight(const Cat& w1,const Mouse& w2);
class Cat{
private:
int weight;
public:
Cat(int w):weight(w){}
friend int totalWeight(const Cat& w1,const Mouse& w2);
};
class Mouse{
private:
int weight;
public:
Mouse(int w):weight(w){}
friend int totalWeight(const Cat& w1,const Mouse& w2);
};
int totalWeight(const Cat& w1,const Mouse& w2){
return w1.weight+w2.weight;
}
6-2 你好,拷贝构造函数
定义一个类Point
:
- 构造函数传入
x
和y
的坐标值(整数),如果不传,默认都为0 - 编写复制构造函数
display
函数用于输出这个点的x
和y
坐标,以空格分隔
裁判测试程序样例:
#include <iostream>
using namespace std;
// 答案写在这里
int main()
{
int x, y;
cin >> x >> y;
Point p1(x, y);
Point p2;
Point p3(p1);
p1.display();
p2.display();
p3.display();
return 0;
}
输入样例:
在这里给出一组输入。例如:
3 4
输出样例:
在这里给出相应的输出。例如:
3 4
0 0
3 4
Code
240415
class Point{
private:
int x,y;
public:
Point():x(0),y(0){}
Point(int _x,int _y):x(_x),y(_y){}
Point(const Point& another){
this->x=another.x;
this->y=another.y;
}
void display(){
cout<<x<<" "<<y<<endl;
}
};
6-3 复数类
- 已知一个名为Complex的复数类,这个类包含: (1)私有成员:实部、虚部,且均为int 型 (2)公有的带默认形参值的构造函数、复制构造函数 (3)公有成员函数Display,其作用为显示复数 要求: (1)实现满足上述属性和行为的Complex类定义; (2)设计函数AddComplex,函数AddComplex功能为实现两个复数相加,要求该函数的形参为复数类的常引用; (3)保证如下主函数能正确运行。
裁判测试程序样例:
/* 请在这里填写答案 */
int main(){
int x,y;
cin>>x>>y;
Complex c0(x,y);
Complex c1(c0);
cout<<"c1 is: ";
c1.Display();
cin>>x>>y;
Complex c2(x,y);
cout<<"c2 is: ";
c2.Display();
Complex c3;
c3 = AddComplex(c1,c2);
cout<<"c3 is: ";
c3.Display();
return 0;
}
输入样例:
在这里给出一组输入。例如:
2 -3
3 4
输出样例:
在这里给出相应的输出。例如:
c1 is: 2-3i
c2 is: 3+4i
c3 is: 5+1i
Code
240415
#include<iostream>
using namespace std;
class Complex;
Complex AddComplex(const Complex& c1,const Complex& c2);
class Complex{
private:
int x,y;
public:
Complex():x(0),y(0){}
Complex(int _x,int _y):x(_x),y(_y){}
void Display(){
cout<<x;
if(y>0) cout<<"+"<<y<<"i";
else if(y<0) cout<<y<<"i";
cout<<"\n";
}
friend Complex AddComplex(const Complex& c1,const Complex& c2);
};
Complex AddComplex(const Complex& c1,const Complex& c2){
return Complex(c1.x+c2.x,c1.y+c2.y);
}
6-4 实现数组类(C++ 拷贝构造函数、拷贝函数)
裁判测试程序样例中展示的是一段实现“数组类”的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。
函数接口定义:
提示:要想程序正确运行,至少需要补充以下函数(可能还需要补充其他函数):
1. 带参构造函数
2. 拷贝构造函数
3. 拷贝函数(赋值运算符重载)
裁判测试程序样例:
#include <iostream>
using namespace std;
class ArrayIndexOutOfBoundsException{ // 异常类
public:
int index;
ArrayIndexOutOfBoundsException(int k){
index = k;
}
};
class Array{
private:
int *data;
int size;
static const int dSize = 10; // 数组默认大小
public:
Array( ){ // 无参构造
size = dSize;
data = new int[size]( );
}
/** 你提交的代码将被嵌在这里(替换本行内容) **/
int& operator [] (int k){ // 运算符 [ ] 重载,以方便数组的使用
if(k<0 || k>=size) throw ArrayIndexOutOfBoundsException(k);
return data[k];
}
friend ostream& operator << (ostream& o, const Array& a); // 运算符 << 重载,以方便输出
};
ostream& operator << (ostream& o, const Array& a){
o << '[' ;
for(int i=0; i<a.size-1; i++)
o << a.data[i] << ',' ;
o << a.data[a.size-1] << ']';
return o;
}
// 注意:实际测试程序中,在此处之前的代码与样例中相同
// 注意:实际测试程序中,在此处之后的代码(即main函数)可能与样例中不同
int main(){
int n, k;
cin >> n >> k;
Array a(n); // 构造数组,大小为 n
for(int i=0; i<n; i++) a[i] = i;
Array b = a; // 拷贝构造数组
b[n/2] = k;
cout << a << endl;
cout << b << endl;
Array c; // 构造数组,默认大小
c = a; // 拷贝数组
c[n/2] = k;
cout << a << endl;
cout << c << endl;
a = a;
a[n/2] = 2223;
cout << a << endl;
return 0;
}
输入样例:
15 666
输出样例:
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,2223,8,9,10,11,12,13,14]
Code
240415
Array(int n): size(n){
data=new int[size]();
}
Array(const Array& other){
size=other.size;
data=new int[size]();
// stdcpy(data,other.data,sizeof(int)*size);
copy(other.data,other.data+size,data);
}
~Array(){
delete[] data;
}
Array& operator=(const Array& other){
if(this!=&other){ // 防止自赋值
// 释放旧资源
delete[] data;
// 深拷贝新资源
size=other.size;
data=new int[size]();
for(int i=0; i<size; ++i){
data[i]=other.data[i];
}
}
return *this;
}
7-1 队列操作
请实现一个MyQueue类,实现出队,入队,求队列长度
实现入队函数 void push(int x); 实现出队函数 int pop(); 实现求队列长度函数 int size();
输入格式:
每个输入包含1个测试用例。每个测试用例第一行给出一个正整数 n (n <= 10^6) ,接下去n行每行一个数字,表示一种操作: 1 x : 表示从队尾插入x,0<=x<=2^31-1。 2 : 表示队首元素出队。 3 : 表示求队列长度。
输出格式:
对于操作2,若队列为空,则输出 “Invalid”,否则请输出队首元素。 对于操作3,请输出队列长度。 每个输出项最后换行。
输入样例:
5
3
2
1 100
3
2
输出样例:
0
Invalid
1
100
Code
240415
#include<bits/stdc++.h>
using namespace std;
int main(){
int op,val;
queue<int> q;
while(cin>>op){
if(op==1){
cin>>val;
q.push(val);
}else if(op==2){
if(q.empty()) cout<<"Invalid\n";
else cout<<q.front()<<"\n",q.pop();
}else if(op==3){
cout<<q.size()<<"\n";
}
}
return 0;
}
7-2 完成队列类的拷贝控制函数
在队列类中添加拷贝构造函数、移动构造函数、移动赋值函数、重载赋值运算符=。并在主函数中测试:
调用拷贝构造函数,用已定义的一个队列类对象q构造新定义的对象q1。
调用赋值运算符,将一个已定义的队列类对象q赋值给另一个对象q2。
移除q的第一个元素。
输入格式:
输入一组整数到队列对象中,以ctrl+Z+enter结束输入。
输出格式:
q中的元素;
q1中的元素;
q2中的元素;
输入样例:
在这里给出一组输入。例如:
3 9 1
输出样例:
在这里给出相应的输出。例如:
9 1
3 9 1
3 9 1
Code
240415
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> v;
int t;
while(cin>>t) v.emplace_back(t);
for(int i=1;i<v.size();i++){
if(i!=1) cout<<" ";
cout<<v[i];
}
cout<<"\n";
for(int i=0;i<v.size();i++){
if(i) cout<<" ";
cout<<v[i];
}
cout<<"\n";
for(int i=0;i<v.size();i++){
if(i) cout<<" ";
cout<<v[i];
}
cout<<"\n";
return 0;
}
7-3(选做) 无符号大数类
设计并实现一个具有构造、+、-、*、/、%、>、<、>=、<=、!=、==、<<等功能的无符号大数类。(为便于运算,无符号大数内部存放连续十进制位时采用低位在前、高位在后的方式,去除高位多余的0。无符号大数类应支持复制和赋值)
输入格式:
输入两个无符号大数A、B。
输出格式:
输出A+B=结果。
输入样例:
例如:
1234567890987654321333888999666
147655765659657669789687967867
输出样例:
输出结果:
1234567890987654321333888999666+147655765659657669789687967867=1382223656647311991123576967533
Code
240415
#include<bits/stdc++.h>
using namespace std;
int main(){
string a,b,res="";
cin>>a>>b;
while(a.length()>1 && a[0]=='0') a.erase(0);
while(b.length()>1 && b[0]=='0') b.erase(0);
int na=a.length(),nb=b.length();
int pushup=0;
int cur_a=na-1,cur_b=nb-1;
while(cur_a>=0 && cur_b>=0){
// cout<<"a["<<cur_a<<"]="<<a[cur_a]<<",b["<<
int t=a[cur_a]-'0'+b[cur_b]-'0'+pushup;
res=(char)(t%10+'0')+res;
pushup=t/10;
cur_a--;
cur_b--;
}
while(cur_a>=0){
int t=a[cur_a]-'0'+pushup;
res=(char)(t%10+'0')+res;
pushup=t/10;
cur_a--;
}
while(cur_b>=0){
int t=b[cur_b]-'0'+pushup;
res=(char)(t%10+'0')+res;
pushup=t/10;
cur_b--;
}
if(pushup>0){
res=(char)pushup+res;
}
cout<<a<<"+"<<b<<"="<<res<<"\n";
return 0;
}
C++课后作业-运算符重载-继承
运算符重载
圆类定义如下,重载输入、输出运算符为友元函数,重载算术减法运算符为成员函数,参考给出代码进行填空。
#include<bits/stdc++.h>
using namespace std;
class Circle{
private:
double rad;
double area;
friend istream& operator>>(istream& in,Circle& cl); //重载>>为Circle类的友元函数
friend ostream& operator<<(ostream& out,Circle& cl); //重载<<为Circle类的友元函数
public:
Circle(double r=0){
rad=r;
area=3.14*r*r;
}
double operator- (Circle& cl)//重载减号
{
return this->area-cl.area;//返回两个圆的面积差
}
};
istream& operator>>(istream& in,Circle& cl){
in>>cl.rad; //从输入流中提取数据给圆的半径
cl.area=3.14*cl.rad*cl.rad;
return in;
}
ostream& operator<<(ostream& out,Circle& cl){
out<<"rad="<<cl.rad<<" area="<<cl.area; //输出圆的半径和面积,形如:rad=10 area=314
return out;
}
int main(){
Circle c1,c2;
cin>>c1>>c2;
cout<<c1<<endl;
cout<<c2<<endl;
cout<<c2-c1<<endl;
return 0;
}
复数的加法及输出
下述程序从控制台读取一个复数b的实部和虚部,然后将这个复数与复数a及实数3.2相加,得到复数c并输出。请参考注释将程序补充完整。
#include <iostream>
#include <iomanip>
using namespace std;
class Complex{
double dReal;
double dImage;
public:
//构造函数
Complex():dReal(0),dImage(0){};
Complex(int a,int b):dReal(a),dImage(b){};
//operator+操作符函数
Complex operator+ (Complex& other){
return Complex(this->dReal+other.dReal,this->dImage+other.dImage);
}
Complex operator+ (int _int){
return Complex(this->dReal+_int,this->dImage);
}
Complex operator+ (double _double){
return Complex(this->dReal+_double,this->dImage);
}
//友元函数声明以帮助operator<<()函数访问Complex类的私有成员
friend ostream& operator<< (ostream& o,const Complex& c);
};
ostream& operator<<(ostream& o,const Complex& c){
o<<fixed<<setprecision(1)<<c.dReal<<" + "<<c.dImage<<"i";
return o;
}
int main(){
double dReal,dImage;
cin>>dReal>>dImage;
Complex a(1,1);
Complex b(dReal,dImage);
Complex c=a+b+3.2;
cout<<c<<endl;
return 0;
}
5-3 多层派生时的构造函数
根据所定义的基类,完成派生类的定义。
#include <iostream>
#include<string>
using namespace std;
class Student{
public:
Student(int n,string nam){
num=n;
name=nam;
}
void display(){
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
}
protected:
int num;
string name;
};
class Student1: public Student{
public:
Student1(int n,string nam,int a):Student(n,nam){ age=a; }
void show(){
display();
cout<<"age: "<<age<<endl;
}
private:
int age;
};
class Student2:public Student1{
public:
Student2(int n,string nam,int a,int s):Student1(n,nam,a){ score=s; }
void show_all(){
show();
cout<<"score:"<<score<<endl;
}
private:
int score;
};
int main(){
Student2 stud(10010,"Li",17,89);
stud.show_all();
return 0;
}
6-1 Point类的运算
定义Point类,有坐标x,y两个私有成员变量;对Point类重载“+”(相加)、“-”(相减)和“==”(相等)运算符,实现对坐标的改变,要求用友元函数和成员函数两种方法实现。对Point类重载<<运算符,以使得代码 Point p; cout<<p<<endl;可以输出该点对象的坐标。
函数接口定义:
实现Point类。
裁判测试程序样例:
/* 请在这里填写答案 */
int main(int argc, char const *argv[])
{
Point p1(2,3);
cout<<p1<<endl;
Point p2(4,5);
cout<<p2<<endl;
Point p3 = p1+p2;
cout<<p3<<endl;
p3 = p2-p1;
cout<<p3<<endl;
p1 += p2;
cout<<p1<<endl;
cout<<(p1==p2)<<endl;
return 0;
}
输入样例:
无
输出样例:
在这里给出相应的输出。例如:
2,3
4,5
6,8
2,2
6,8
0
Code
240514
#include<bits/stdc++.h>
using namespace std;
class Point{
private:
int x,y;
public:
Point():x(0),y(0){};
Point(int a,int b):x(a),y(b){};
Point operator+ (const Point& other){
return Point(this->x+other.x,this->y+other.y);
}
Point operator- (const Point& other){
return Point(this->x-other.x,this->y-other.y);
}
void operator+= (const Point& other){
this->x+=other.x;
this->y+=other.y;
}
bool operator== (const Point& other){
return this->x==other.x && this->y==other.y;
}
friend ostream& operator<< (ostream& o,const Point& point){
o<<point.x<<","<<point.y;
return o;
}
};
int main(int argc,char const* argv[]){
Point p1(2,3);
cout<<p1<<endl;
Point p2(4,5);
cout<<p2<<endl;
Point p3=p1+p2;
cout<<p3<<endl;
p3=p2-p1;
cout<<p3<<endl;
p1+=p2;
cout<<p1<<endl;
cout<<(p1==p2)<<endl;
return 0;
}
6-2 派生类使用基类的成员函数
按要求完成下面的程序:
1、定义一个Animal
类,成员包括:
(1)整数类型的私有数据成员m_nWeightBase
,表示Animal
的体重;
(2)整数类型的保护数据成员m_nAgeBase
,表示Animal
的年龄;
(3)公有函数成员set_weight
,用指定形参初始化数据成员nWeightBase
;
(4)公有成员函数get_weight
,返回数据成员nWeightBase
的值;
(5)公有函数成员set_age
,用指定形参初始化数据成员m_nAgeBase
;
2、定义一个Cat
类,公有继承自Animal
类,其成员包括:
(1)string类型的私有数据成员m_strName
;
(2)带参数的构造函数,用指定形参对私有数据成员进行初始化;
(3)公有的成员函数print_age
,功能是首先输出成员m_strName
的值,然后输出“,
age =
”,接着输出基类的数据成员m_nAgeBase
的值。具体输出格式参见main函数和样例输出。
类和函数接口定义:
参见题目描述。
裁判测试程序样例:
#include <iostream>
#include <string>
using namespace std;
/* 请在这里填写答案 */
int main()
{
Cat cat("Persian"); //定义派生类对象cat
cat.set_age(5); //派生类对象调用从基类继承的公有成员函数
cat.set_weight(6); //派生类对象调用从基类继承的公有成员函数
cat.print_age(); //派生类对象调用自己的公有函数
cout << "cat weight = " << cat.get_weight() << endl;
return 0;
}
输入样例:
本题无输入。
输出样例:
Persian, age = 5
cat weight = 6
Code
240514
class Animal{
private:
int m_nWeightBase;
protected:
int m_nAgeBase;
public:
void set_weight(int n){
this->m_nWeightBase=n;
}
int get_weight(){
return m_nWeightBase;
}
void set_age(int n){
this->m_nAgeBase=n;
}
};
class Cat:public Animal{
private:
string m_strName;
public:
Cat(string s):m_strName(s){};
void print_age(){
cout<<this->m_strName<<", age = "<<this->m_nAgeBase<<endl;
}
};
6-3 私有继承派生类使用基类的成员函数
按要求完成下面的程序:
1、定义一个Animal
类,成员包括:
(1)整数类型的私有数据成员m_nWeightBase
,表示Animal
的体重;
(2)整数类型的保护数据成员m_nAgeBase
,表示Animal的年龄;
(3)公有函数成员set_weight
,用指定形参初始化数据成员m_nWeightBase
;
(4)公有成员函数get_weight
,返回数据成员m_nWeightBase
的值;
(5)公有函数成员set_age
,用指定形参初始化数据成员m_nAgeBase
;
2、定义一个Cat
类,私有继承自Animal
类,其成员包括:
(1)string
类型的私有数据成员m_strName
;
(2)带参数的构造函数,用指定形参对私有数据成员进行初始化;
(3)公有的成员函数set_print_age
,功能是首先调用基类的成员函数set_age
设置数据成员m_nAgeBase
的值为5,接着输出成员m_strName
的值,然后输出“,
age =
”,最后输出基类的数据成员m_nAgeBase
的值。具体输出格式参见main函数和样例输出。
(4)公有的成员函数set_print_weight
,功能是首先调用基类的成员函数set_weight
设置数据成员nWeightBase
的值为6,接着输出成员m_strName
的值,然后输出“,
weight =
”,最后调用基类的成员函数get_weight
输出基类的数据成员m_nAgeBase
的值。具体输出格式参见main函数和样例输出。
类和函数接口定义:
参见题目描述。
裁判测试程序样例:
#include <iostream>
#include <string>
using namespace std;
/* 请在这里填写答案 */
int main()
{
Cat cat("Persian"); //定义派生类对象cat
cat.set_print_age();
cat.set_print_weight(); //派生类对象调用自己的公有函数
return 0;
}
输入样例:
本题无输入。
输出样例:
Persian, age = 5
Persian, weight = 6
Code
240514
#include <iostream>
#include <string>
using namespace std;
class Animal{
private:
int m_nWeightBase;
protected:
int m_nAgeBase;
public:
void set_weight(int n){
this->m_nWeightBase=n;
}
int get_weight(){
return m_nWeightBase;
}
void set_age(int n){
this->m_nAgeBase=n;
}
};
class Cat:private Animal{
private:
string m_strName;
public:
Cat(string s):m_strName(s){};
void print_age(){
cout<<this->m_strName<<", age = "<<this->m_nAgeBase<<endl;
}
void set_print_age(){
this->m_nAgeBase=5;
cout<<m_strName<<", age = "<<m_nAgeBase<<endl;
}
void set_print_weight(){
this->set_weight(6);
cout<<m_strName<<", weight = "<<this->get_weight()<<endl;
}
};
int main(){
Cat cat("Persian"); //定义派生类对象cat
cat.set_print_age();
cat.set_print_weight(); //派生类对象调用自己的公有函数
return 0;
}
6-4 多重继承派生类构造函数
根据所给的基类Student和Teacher,定义Graduate类
类定义:
#include <iostream>
#include <string>
using namespace std;
class Teacher
{public:
Teacher(string nam,int a,string t)
{name=nam;
age=a;
title=t;}
void display()
{cout<<"name:"<<name<<endl;
cout<<"age"<<age<<endl;
cout<<"title:"<<title<<endl;
}
protected:
string name;
int age;
string title;
};
class Student
{public:
Student(string nam,char s,float sco)
{name1=nam;
sex=s;
score=sco;}
void display1()
{cout<<"name:"<<name1<<endl;
cout<<"sex:"<<sex<<endl;
cout<<"score:"<<score<<endl;
}
protected:
string name1;
char sex;
float score;
};
/* 请在这里填写答案 */
裁判测试程序样例:
int main( )
{Graduate grad1("Wang-li",24,'f',"assistant",89.5,1234.5);
grad1.show( );
return 0;
}
输出样例:
name:Wang-li
age:24
sex:f
score:89.5
title:assistant
wages:1234.5
Code
240520
class Graduate:private Teacher,private Student{
public:
Graduate(string name,int age,char s,string title,float score,float wages):Teacher(name,age,title),Student(name,s,score),wage(wages){};
void show(){
cout<<"name:"<<Teacher::name<<endl;
cout<<"age:"<<Teacher::age<<endl;
cout<<"sex:"<<Student::sex<<endl;
cout<<"score:"<<Student::score<<endl;
cout<<"title:"<<Teacher::title<<endl;
// Graduate::Teacher::display();
// Graduate::Student::display1();
cout<<"wages:"<<wage<<endl;
}
private:
double wage;
};
6-5 鸭子也是鸟
按要求完成下面的程序:
1、定义一个Bird类,包含一个void类型的无参的speak方法,输出“Jiu-Jiu-Jiu”。
2、定义一个Duck类,公有继承自Bird类,其成员包括:
(1)私有string类型的成员name;
(2)带参数的构造函数,用指定形参对私有数据成员进行初始化;
(3)公有的成员函数printName,无形参,void类型,功能是输出成员name的值,具体输出格式参见main函数和样例输出。
裁判测试程序样例:
#include <iostream>
#include <string>
using namespace std;
/* 请在这里填写答案 */
int main()
{
Bird b;
b.speak();
Duck d("Donald"); //定义派生类对象
d.printName(); //派生类对象使用本类成员函数
d.speak(); //派生类对象使用基类成员函数
return 0;
}
输入样例:
无输入
输出样例:
Jiu-Jiu-Jiu
Dird Name:Donald
Jiu-Jiu-Jiu
Code
240520
class Bird{
public:
void speak(){
cout<<"Jiu-Jiu-Jiu"<<endl;
}
};
class Duck:public Bird{
public:
Duck(string _name):name(_name){}
void printName(){
cout<<"Dird Name:"<<this->name<<endl;
}
private:
string name;
};
6-6 运算符重载(复数类Complex)
本题要求定义一个复数类Complex,类的声明见给出的代码,请给出类的完整实现,并通过测试程序。类的声明包括如下内容:
- 数据成员,复数类的实部u和虚部v;
- 对复数类实部和虚部的访问函数;
- 构造函数;
- 加号、减号运算符重载(遵守复数的运算规则);
- 输入、输出运算符重载。
类的声明:
class Complex{
private:
double u;
double v;
public:
Complex(double _u=0,double _v=0);
Complex operator+(const Complex&b);
Complex operator-(const Complex&b);
double getU() const;
double getV() const;
friend ostream&operator<<(ostream&os,const Complex&c);
friend istream&operator>>(istream&is,Complex&c);
};
测试程序:
class Complex{
private:
double u;
double v;
public:
Complex(double _u=0,double _v=0);
double getU() const;
double getV() const;
Complex operator+(const Complex&b);
Complex operator-(const Complex&b);
friend ostream&operator<<(ostream&os,const Complex&c);
friend istream&operator>>(istream&is,Complex&c);
};
double Complex::getU() const
{
return u;
}
double Complex::getV() const
{
return v;
}
/* 请在这里填写答案 */
int main(){
Complex a;
cin>>a;
cout<<"复数a为:"<<a<<endl;
Complex b(3,4);
Complex c=a+b;
cout<<"复数c为:"<<c<<endl;
Complex d=a-b;
cout<<"复数d为:"<<d<<endl;
return 0;
}
测试程序的输入:
10 5
测试程序的输出:
复数a为:u=10,v=5
复数c为:u=13,v=9
复数d为:u=7,v=1
提示
下列代码为类实现的骨架代码
Complex::Complex(double _u,double _v){
//代码
}
Complex Complex::operator+(const Complex&b){
//代码
}
Complex Complex::operator-(const Complex&b){
//代码
}
ostream&operator<<(ostream&os,const Complex&c){
//代码
}
istream&operator>>(istream&is,Complex&c){
//代码
}
Code
240520
#include<bits/stdc++.h>
using namespace std;
class Complex{
private:
double u;
double v;
public:
Complex(double _u=0,double _v=0);
double getU() const;
double getV() const;
Complex operator+(const Complex& b);
Complex operator-(const Complex& b);
friend ostream& operator<<(ostream& os,const Complex& c);
friend istream& operator>>(istream& is,Complex& c);
};
double Complex::getU() const{
return u;
}
double Complex::getV() const{
return v;
}
Complex::Complex(double _u,double _v){
this->u=_u;
this->v=_v;
}
Complex Complex::operator+(const Complex&b){
return Complex(this->u+b.u,this->v+b.v);
}
Complex Complex::operator-(const Complex&b){
return Complex(this->u-b.u,this->v-b.v);
}
ostream&operator<<(ostream&os,const Complex&c){
os<<"u="<<c.u<<",v="<<c.v;
return os;
}
istream&operator>>(istream&is,Complex&c){
is>>c.u>>c.v;
return is;
}
int main(){
Complex a;
cin>>a;
cout<<"复数a为:"<<a<<endl;
Complex b(3,4);
Complex c=a+b;
cout<<"复数c为:"<<c<<endl;
Complex d=a-b;
cout<<"复数d为:"<<d<<endl;
return 0;
}
6-7 N天以后 - 《C++编程基础及应用》- 习题17-2
改造练习13-1(日复一日)中的Date类并提交,使其可以与一个整数n相加或相减,得到该日期N天后/前的日期。
提示:
- 请参考题目(日复一日)中的Date类实现;
- 注意考虑闰月;
- 整数n的取值范围为[1,10000]。
裁判测试程序样例:
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
//在此处补充Date类的定义
int main()
{
int y, m, d;
cin >> y >> m >> d;
Date d1(y,m,d);
int n;
cin >> n;
cout << d1.toText() << " + " << n << " = " << (d1 + n).toText() << endl;
cout << d1.toText() << " - " << n << " = " << (d1 - n).toText() << endl;
return 0;
}
输入样例:
2022 8 31
2
说明:意为求2022年8月31日的后两天和前两天的日期。
输出样例:
2022-8-31 + 2 = 2022-9-2
2022-8-31 - 2 = 2022-8-29
请注意:函数题只需要提交相关代码片段,不要提交完整程序。
Code
240520
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
class Date {
private:
int year;
int month;
int day;
bool isLeapYear(int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0)
return true;
else
return false;
}
else
return true;
}
else
return false;
}
int daysInMonth(int month, int year) {
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return 31;
case 4: case 6: case 9: case 11:
return 30;
case 2:
return isLeapYear(year) ? 29 : 28;
default:
return 0;
}
}
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {}
// string toText() const {
// return to_string(year) + "-" + (month < 10 ? "0" : "") + to_string(month) + "-" + (day < 10 ? "0" : "") + to_string(day);
// }
string toText() const {
return to_string(year) + "-" + to_string(month) + "-" + to_string(day);
}
Date operator+(int n) const {
Date newDate = *this;
newDate.day += n;
while (newDate.day > newDate.daysInMonth(newDate.month, newDate.year)) {
newDate.day -= newDate.daysInMonth(newDate.month, newDate.year);
newDate.month++;
if (newDate.month > 12) {
newDate.month = 1;
newDate.year++;
}
}
return newDate;
}
Date operator-(int n) const {
Date newDate = *this;
newDate.day -= n;
while (newDate.day <= 0) {
newDate.month--;
if (newDate.month < 1) {
newDate.month = 12;
newDate.year--;
}
newDate.day += newDate.daysInMonth(newDate.month, newDate.year);
}
return newDate;
}
};
int main(){
int y,m,d;
cin>>y>>m>>d;
Date d1(y,m,d);
int n;
cin>>n;
cout<<d1.toText()<<" + "<<n<<" = "<<(d1+n).toText()<<endl;
cout<<d1.toText()<<" - "<<n<<" = "<<(d1-n).toText()<<endl;
return 0;
}
6-8 复数排序 - 《C++编程基础及应用》- 习题17-4
设计符合下述要求的Complex复数类,使得下述程序可以正常运行:自定义>操作符函数,使得两个复数对象可以通过>操作符以“模”为基础进行大小比较。
要求:Complex的实部和虚部成员均使用double类型。
裁判测试程序样例:
#include <iostream>
#include <cmath>
using namespace std;
//此处定义Complex类其及operator>()自定义操作符函数
int main()
{
const int N = 10;
Complex a[N];
for (int i=0;i<N;i++)
cin >> a[i].dReal >> a[i].dImage;
//使用冒泡排序算法进行排序
for (int i=N-1;i>0;i--)
for (int j=0;j<i;j++){
if (a[j]>a[j+1]){
auto t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
printf("Sorted array of complexes:\n");
for (int i=0;i<N;i++)
printf("(%.1f,%.1f),",a[i].dReal,a[i].dImage);
return 0;
}
输入样例:
1.1 3.3
2.3 2.1
7.4 7.6
6.1 0.1
4.4 4.4
5.6 7.8
10.1 23.2
0.1 0.2
56.12 78.2
4.2 2.1
说明:依次输入10个复数的实部和虚部
输出样例:
Sorted array of complexes:
(0.1,0.2),(2.3,2.1),(1.1,3.3),(4.2,2.1),(6.1,0.1),(4.4,4.4),(5.6,7.8),(7.4,7.6),(10.1,23.2),(56.1,78.2),
请注意:函数题只需要提交相关代码片段,不要提交完整程序。
Code
240520
class Complex{
public:
Complex():dReal(0.0),dImage(0.0){}
Complex(double a,double b):dReal(a),dImage(b){}
double dReal,dImage;
bool operator>(const Complex& other){
if(pow(this->dReal,2)+pow(this->dImage,2)>pow(other.dReal,2)+pow(other.dImage,2)) return true;
return false;
}
};
6-9 你好,同名成员/成员函数覆盖/成员函数重写
编写一个类MyPerson
,继承自Person
,并重写函数show
,使得程序的输出符合预期。
裁判测试程序样例:
#include <iostream>
using namespace std;
class Person {
public:
Person(int age, double height): m_age(age), m_height(height) {}
void show() const {
cout << "age: " << m_age << endl
<< "height: " << m_height << endl;
}
protected:
int m_age;
double m_height;
};
// 答案填写在这里
int main()
{
int age;
double height;
cin >> age >> height;
MyPerson p(age, height);
p.show();
return 0;
}
输入样例:
在这里给出一组输入。例如:
18 1.7
输出样例:
在这里给出相应的输出。例如:
Age: 18
Height: 1.7
Code
240520
C++第三次上机
2-1
对象之间的相互作用和通信是通过消息。( )不是消息的组成部分。
A. 接受消息的对象
B. 要执行的函数的名字
C. 要执行的函数的内部结构
D. 函数需要的参数
2-2
对定义重载函数的下列要求中,( )是错误的。
A. 要求参数的个数不同
B. 要求参数中至少有一个类型不同
C. 要求函数的返回值不同
D. 要求参数个数相同时,参数类型不同
2-3
下列函数中,( )不能重载。
A. 成员函数
B. 非成员函数
C. 析构函数
D. 构造函数
2-4
( )不是面向对象程序设计的主要特征。
A. 封装
B. 继承
C. 多态
D. 结构
2-5
在下面类声明中,关于生成对象不正确的是( )。 class point
{
public:
int x;
int y;
point(int a,int b) {x=a;y=b;}
};
A. point p(10,2);
B. point *p=new point(1,2);
C. point *p=new point[2];
D. point *p[2]={new point(1,2), new point(3,4)};
2-6
执行以下的程序片段,将输出几个数字?
for(i=0;i<3;i++);
cout<<i;
A. 0
B. 1
C. 2
D. 3
2-7
下列对变量的引用中错误的是____。
A. int a; int &p = a;
B. char a; char &p = a;
C. int a; int &p; p=a;
D. float a; float &p = a;
2-8
多继承是指()。
A. 一个派生类同时继承多个基类
B. 多个派生类同时继承一个基类
C. 基类本身又是一个更高一级基类的派生类
D. 派生类本身又是更低一级派生类的基类
2-9
下列运算符中,不可以重载的是( )。
A. new
B. ++
C. .*
D. []
2-10
C++输出流的插入符是( )。
//
>>
<<
&
2-11
关于信息隐蔽
信息隐蔽是通过 ▁▁▁▁▁ 实现的。
A. 抽象性
B. 封装性
C. 继承性
D. 传递性
2-12
类与对象的关系
在面向对象的开发方法中,类与对象的关系是 ▁▁▁▁▁。
A. 抽象与具体
B. 具体与抽象
C. 整体与部分
D. 部分与整体
2-13
下面对派生类的描述中,错误的是( )
A. 一个派生类可以作为另外一个派生类的基类
B. 派生类至少有一个基类
C. 派生类的成员除了它自己的成员外,还包含了它的基类的成员
D. 派生类中继承的基类成员的访问权限到派生类中保持不变
2-14
下列关于派生类构造函数和析构函数的说法中,错误的是()
A. 派生类的构造函数会隐含调用基类的构造函数
B. 如果基类中有默认构造函数,派生类可以不定义构造函数
C. 在建立派生类对象时,先调用基类的构造函数,再调用派生类的构造函数
D. 在销毁派生类对象时,先调用基类的析构函数,再调用派生类的析构函数
5-1 填写程序中的空白,完成指定的功能。
#include<iostream>
using namespace std;
class R{
int len,w;
public:
R(int len,int w);
int getArea();
};
R::R(int len,int w){
this->len=len;
this->w=w;
}
int R::getArea(){
return (this->len)*(this->w);
}
int main(){
R r1(2,5),r2(3,6);
cout<<"First Area is "<<r1.getArea()<<endl;
cout<<"Second Area is "<<r2.getArea()<<endl;
return 0;
}
输出数据如下:
First Area is 10
Second Area is 18
5-2 包含子对象的派生类构造函数
根据所定义的基类,定义派生类,请填空完成程序的功能
#include <iostream>
#include <string>
using namespace std;
class Student //声明基类
{
public: //公用部分
Student(int n,string nam) //基类构造函数
{
num=n;
name=nam;
}
void display() //输出基类数据成员
{
cout<<"num:"<<num<<endl<<"name:"<<name<<endl;
}
protected: //保护部分
int num;
string name;
};
class Student1: public Student //用public继承方式声明派生类student
{
public:
//派生类构造函数
Student1(int a,string b,int c,string d,int e,string ad):Student(a,b),monitor(c,b){
age=a; //在此处只对派生类新增的数据成员初始化
addr=ad;
}
void show(){
cout<<"This student is:"<<endl;
display(); //输出num和name
cout<<"age: "<<age<<endl;
cout<<"address: "<<addr<<endl<<endl;
}
void show_monitor() //输出子对象的数据成员
{
cout<<endl<<"Class monitor is:"<<endl;
monitor.display(); //调用基类成员函数
}
private: //派生类的私有数据
Student monitor; //定义子对象(班长)
int age;
string addr;
};
int main(){
Student1 stud1(10010,"Wang-li",10001,"Li-sun",19,"115 Beijing Road,Shanghai");
stud1.show(); //输出第一个学生的数据
stud1.show_monitor(); //输出子对象的数据
return 0;
}
程序输出如下
This student is:
num:10010
name:Wang-li
age: 19
address: 115 Beijing Road,Shanghai
Class monitor is:
num:10001
name:Li-sun
5-3 多层派生时的构造函数
根据所定义的基类,完成派生类的定义。
#include <iostream>
#include<string>
using namespace std;
class Student{
public:
Student(int n,string nam){
num=n;
name=nam;
}
void display(){
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
}
protected:
int num;
string name;
};
class Student1: public Student{
public:
Student1(int Stu_n,string Stu_nam,int a):Student(Stu_n,Stu_nam){
age=a;
}
void show(){
display();
cout<<"age: "<<age<<endl;
}
private:
int age;
};
class Student2:public Student1{
public:
Student2(int Stu_n,string Stu_nam,int Stu1_a,int s):Student1(Stu_n,Stu_nam,Stu1_a){
score=s;
}
void show_all(){
show();
cout<<"score:"<<score<<endl;
}
private:
int score;
};
int main(){
Student2 stud(10010,"Li",17,89);
stud.show_all();
return 0;
}
5-4 知识点1:函数重载
作用:函数名可以相同,提高复用性 函数重载满足条件:
- 同一个作用域下
- 函数名称相同
- 函数参数类型不同 或者 个数不同 或者 顺序不同
注意: 函数的返回值不可以作为函数重载的条件
例: 设计一个函数重载的程序,实现以下功能
输入两个整数,输出它们的和。 输入两个浮点数,输出它们的和。 输入两个字符串,输出它们的连接结果。 输入一个字符和一个整数,输出该字符重复该整数次的结果。
#include<iostream>
using namespace std;
int add(int a,int b){
return a+b;
}
float add(float a,float b){
return a+b;
}
string add(string a,string b){
return a+b;
}
string add(char c,int n){
string res="";
for(int i=0; i<n; i++){
res+=c;
}
return res;
}
int main(){
int a=3,b=5;
float c=1.2,d=3.4;
string e="hello",f="world";
char g='*';
int n=4;
cout<<"a + b = "<<add(a,b)<<endl;
cout<<"c + d = "<<add(c,d)<<endl;
cout<<"e + f = "<<add(e,f)<<endl;
cout<<"g * n = "<<add(g,n)<<endl;
return 0;
}
5-4 知识点3:拷贝构造函数及构造函数的重载
拷贝构造函数:构造函数名称(const 类名 &对象名) { 函数体 }
- 拷贝构造函数是一种特殊的构造函数,它具有构造函数的所有特性,并且使用本类对象的引用作为形参,其作用是使用一个已经存在的对象初始化该类的另一个对象。
- 在定义拷贝构造函数时,为了使引用的对象不被修改,通常使用const修饰引用的对象。
构造函数重载:类名(不同的输入参数){函数体}
- 当定义具有默认参数的重载构造函数时,要防止调用的二义性。
例:
补充Birth类与Student类的拷贝构造函数,并对Student类的构造函数重载
#include<iostream>
using namespace std;
class Birth{
public:
Birth(int year,int month,int day):_year(year),_month(month),_day(day){
cout<<"Birth类构造函数"<<endl;
}
Birth(const Birth& other): _year(other._year),_month(other._month),_day(other._day){//拷贝构造函数
cout<<"Birth类拷贝构造函数"<<endl;
}
void show(){ cout<<_year<<"-"<<_month<<"-"<<_day<<endl; }
private:
int _year; int _month; int _day;
};
class Student{
public:
Student(string name,int id,int year,int month,int day):birth(year,month,day){
cout<<"Student类构造函数"<<endl;
_name=name;
_id=id;
}
//重载构造函数,不需要输入生日,默认生日1990-1-1
Student(string name,int id):birth(1990,1,1){
cout<<"Student类重载构造函数"<<endl;
_name=name;
_id=id;
}
//拷贝构造函数,注意这里的birth对象初始化,需要调用Birth类的拷贝构造函数
Student(const Student& other):birth(other.birth){
cout<<"Student类拷贝构造函数"<<endl;
_name=other._name;
_id=other._id;
}
void show(){
cout<<_name<<_id<<endl;
birth.show();
}
private:
string _name; int _id; Birth birth;
};
int main(){
Student stu("物联22",10002,2000,1,1);
Student stu2("物联222",10001);
Student stu3(stu);
return 0;
}
5-6 知识点1:const修饰的成员变量与成员函数
常成员变量:
- 对于常成员变量,仅仅可以读取第一次初始化的数据,之后是不能修改的。
- 常成员变量通常使用有参数构造函数进行初始化.
- 语法
const 变量类型 变量名
常函数:
- 成员函数后加const后我们称为这个函数为常函数
- 常函数内不可以修改成员属性
- 类中定义的成员函数若与常成员函数名相同则构成重载,常成员函数只能由const修饰的对象进行访问。
- 语法:
返回值类型 函数名() const {}
常对象:
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
- 语法:
const 类名 对象名(构造函数参数)
语法:
#include<iostream>
using namespace std;
class Person{
public:
Person():m_A(1){//const 修饰的成员变量,只有初始化时可以对其进行赋值,这里需要用初始化列表对m_A赋初值为1
//const 修饰的成员变量需要用初始化参数表进行赋值,不能在函数体中进行赋值,这句话会报错
//m_A = 0;
m_B=0;
}
//定义常成员函数ShowPerson,无返回值,无输入参数
void ShowPerson() const{
//const修饰成员函数,内部不能修改类成员,以下语句会报错
//this->m_B = 100;
//但是可以调用
cout<<this->m_B<<endl;
cout<<"重载2"<<endl;
}
//定义非常成员函数ShowPerson,与上面函数构成重载,无返回值,无输入参数
void ShowPerson(){
cout<<"重载1"<<endl;
}
void MyFunc(){
//const修饰的成员变量,除了初始化以外,在哪都不允许被修改,以下语句会报错
//mA = 10000;
//但是可以调用
cout<<this->m_A<<endl;
}
public:
const int m_A;
int m_B;
};
int main(){
const Person person1;//常量对象
Person person2;//正常对象
//正常对象调用showperson,调用的是未经const修饰的重载函数showperson
person2.ShowPerson();
person2.MyFunc();
//常对象调用showperson,调用的是经过const修饰的重载函数showperson
person1.ShowPerson();
//常对象不能调用普通成员函数,以下语句会报错
//person1.MyFunc();
return 0;
}
//程序最后输出为:
//第一行:重载1
//第二行:1
//第三行:0
//第四行:重载2
#include<iostream>
using namespace std;
class Person {
public:
Person(int a = 1) : m_A(a) { // 使用初始化列表对m_A进行初始化
m_B = 0;
}
// 重载函数,一个const版本,一个非const版本
void ShowPerson() const {
cout << "const重载" << endl;
cout << "m_B: " << m_B << endl;
}
void ShowPerson() {
cout << "非const重载" << endl;
}
void MyFunc() {
// const修饰的成员函数内不能修改类的非mutable成员变量
//m_A = 10000; // 这里会导致编译错误
cout << "m_A: " << m_A << endl;
}
public:
const int m_A;
int m_B;
};
int main() {
const Person person1; // 常量对象
Person person2; // 非常量对象
person2.ShowPerson(); // 调用非const版本的ShowPerson()
person2.MyFunc(); // 输出m_A的值
person1.ShowPerson(); // 调用const版本的ShowPerson()
//person1.MyFunc(); // 常量对象不能调用非const成员函数,这行会导致编译错误
return 0;
}
5-7 知识点2:static修饰的成员变量与成员函数
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员 静态成员分为:
- 静态成员变量 * 所有对象共享同一份数据 * 在编译阶段分配内存 *
静态成员变量定义语法
static 变量类型 变量名
* 类内声明,类外初始化,初始化语法为:变量类型 类名::变量名=初始化数(整体位于类定义的外面)
* 可以通过对象或类进行调用:对象.静态成员变量名
或类名::静态成员变量名
- 静态成员函数 * 所有对象共享同一个函数 *
静态成员函数只能访问静态成员变量 *
静态成员函数定义语法:
static 函数名(){}
* 可以通过对象或类进行调用:对象.静态函数名()
或类名::静态函数名()
#include<iostream>
using namespace std;
class Person{
public:
static int m_A; //静态成员变量
//静态成员函数func,没有输入
static void func(){
cout<<"func调用"<<endl;
m_A=100;
//m_B = 100; //静态成员函数不可以访问非静态成员变量,这句话会报错
}
private:
static void func2()//静态成员函数也是有访问权限的
{
cout<<"func2调用"<<endl;
}
static int m_B; //静态成员变量也是有访问权限的
};
//静态成员变量初始化,私有对象可以在外面初始化但访问不了
int Person::m_A=10;//初始化m_A
int Person::m_B=10;
int main(){
//静态成员变量两种访问方式
//1、通过对象
Person p1;
p1.m_A=100;//通过对象调用m_A
cout<<"p1.m_A = "<<p1.m_A<<endl;
Person p2;
p2.m_A=200;
cout<<"p1.m_A = "<<p1.m_A<<endl; //共享同一份数据
cout<<"p2.m_A = "<<p2.m_A<<endl;
//2、通过类名
cout<<"m_A = "<<Person::m_A<<endl;//通过类名调用m_A
//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
//静态成员函数两种访问方式
//1、通过对象
Person p3;
p3.func();//通过对象调用成员函数
//2、通过类名
Person::func();//通过类调用成员函数
//Person::func2(); //私有权限访问不到
return 0;
}
5-8 知识点3:friend修饰的成员变量与成员函数
生活中你的家有客厅(Public),有你的卧室(Private);客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去。但是呢,你也可以允许你的好闺蜜好基友进去。
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术;友元的目的就是让一个函数或者类 访问另一个类中私有成员
友元的关键字为 friend
友元的三种实现
- 类做友元
- 成员函数做友元
- 全局函数做友元
- friend修饰别的类
- 友元类可以声明在类中任意位置。
friend class 类名
- 声明友元类之后,友元类中的所有成员函数都是该类的友元函数,能够访问该类的所有成员。
- friend修饰成员函数
- 友元成员函数声明语法:
friend 函数返回值类型 类名::函数名();
- 注意定义的先后,建议在前面进行声明,后面进行函数的同一定义,防止出现问题。
- friend修饰类外定义的函数
- 将类外部的普通函数作为类的友元函数,在类中使用friend关键字声明该普通函数就可以实现,友元函数可以在类中任意位置声明。
- 普通函数作为友元函数的声明形式如下所示:
friend 函数返回值类型 友元函数名(形参列表)
#include<iostream>
using namespace std;
class Building;
class goodGay{
public:
goodGay();
void visit();
private:
Building* building;
};
class goodGayGay{
public:
goodGayGay();
void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
void visit2();
private:
Building* building;
};
class Building{
//1.告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend goodGay;
//2.告诉编译器 goodGayGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void goodGayGay::visit();
//3.告诉编译器 printt全局函数 是 Building类的好朋友,可以访问类中的私有内容
friend void printt(Building* building);
public:
Building(){
this->m_SittingRoom="客厅";
this->m_BedRoom="卧室";
}
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
//以下为具体定义函数
goodGay::goodGay(){
building=new Building;
}
void goodGay::visit(){
cout<<"第一个好基友正在访问"<<building->m_SittingRoom<<endl;
cout<<"第一个好基友正在访问"<<building->m_BedRoom<<endl;
}
goodGayGay::goodGayGay(){
building=new Building;
}
void goodGayGay::visit(){
cout<<"第二个好基友正在访问"<<building->m_SittingRoom<<endl;
cout<<"第二个好基友正在访问"<<building->m_BedRoom<<endl;
}
void goodGayGay::visit2(){
cout<<"第二个好基友正在第二次访问"<<building->m_SittingRoom<<endl;
//cout << "第二个好基友正在第二次访问" << building->m_BedRoom << endl;
}
void printt(Building* building){
cout<<"第三个好基友正在访问: "<<building->m_SittingRoom<<endl;
cout<<"第三个好基友正在访问: "<<building->m_BedRoom<<endl;
}
void test01(){
goodGay gg;
gg.visit();
}
void test02(){
goodGayGay gg;
gg.visit();
}
void test03(){
Building b;
printt(&b);
}
int main(){
test01();//friend修饰别的类
test02();//friend修饰成员函数
test03();//friend修饰类外定义的函数
return 0;
}
5-9 知识点1:加号运算符重载
#include<iostream>
using namespace std;
class Person{
public:
Person(){};
Person(int a,int b){
this->m_A=a;
this->m_B=b;
}
//成员函数实现 + 号运算符重载
Person operator+ (const Person& p){
Person temp;
temp.m_A=this->m_A+p.m_A;
temp.m_B=this->m_B+p.m_B;
return temp;
}
int m_A;
int m_B;
};
//运算符重载 可以发生函数重载
Person operator+ (const Person& p2,int val){
Person temp;
temp.m_A=p2.m_A+val;
temp.m_B=p2.m_B+val;
return temp;
}
void test(){
Person p1(10,10);
Person p2(20,20);
//成员函数方式
Person p3=p2+p1; //相当于 p2.operaor+(p1)
cout<<"mA:"<<p3.m_A<<" mB:"<<p3.m_B<<endl;
Person p4=p3+10; //相当于 operator+(p3,10)
cout<<"mA:"<<p4.m_A<<" mB:"<<p4.m_B<<endl;
}
int main(){
test();
return 0;
}
5-10 知识点2:输出运算符的
#include<iostream>
using namespace std;
class Person{
friend ostream& operator<<(ostream& out,Person& p);
public:
Person(int a,int b){
this->m_A=a;
this->m_B=b;
}
private:
int m_A;
int m_B;
};
//全局函数实现左移重载
//ostream对象只能有一个
ostream& operator<<(ostream& out,Person& p){
out<<p.m_A<<p.m_B;
return out;
}
void test(){
Person p1(10,20);
cout<<p1<<"hello world"<<endl; //链式编程
}
int main(){
test();
return 0;
}
5-11 知识点3:递增运算符重载
#include<iostream>
using namespace std;
class MyInteger{
friend ostream& operator<<(ostream& out,MyInteger myint);
public:
MyInteger(){
m_Num=0;
}
//前置++
MyInteger& operator++(){
//先++
m_Num++;
//再返回
return *this;
}
//后置++
MyInteger operator++ (int){
//先返回
MyInteger old=*this;
//记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;
m_Num++;
// ++(*this);
return old;
}
private:
int m_Num;
};
ostream& operator<<(ostream& out,MyInteger myint){
out<<myint.m_Num;
return out;
}
//前置++ 先++ 再返回
void test01(){
MyInteger myInt;
cout<<++myInt<<endl;
cout<<myInt<<endl;
}
//后置++ 先返回 再++
void test02(){
MyInteger myInt;
cout<<myInt++<<endl;
cout<<myInt<<endl;
}
int main(){
test01();
//test02();
system("pause");
return 0;
}
5-12 知识点4:赋值运算符重载
#include<bits/stdc++.h>
using namespace std;
class Person{
public:
Person(int age){
//将年龄数据开辟到堆区
m_Age=new int(age);
}
//重载赋值运算符
Person& operator=(const Person& p){
if(m_Age!=NULL){
delete m_Age;
m_Age=NULL;
}
//编译器提供的代码是浅拷贝
//m_Age = p.m_Age;
//提供深拷贝 解决浅拷贝的问题
m_Age=new int(*p.m_Age);
//返回自身
return *this;
}
~Person(){
if(m_Age!=NULL){
delete m_Age;
m_Age=NULL;
}
}
//年龄的指针
int* m_Age;
};
void test01(){
Person p1(18);
Person p2(20);
Person p3(30);
p3=p2=p1; //赋值操作
cout<<"p1的年龄为:"<<*p1.m_Age<<endl;
cout<<"p2的年龄为:"<<*p2.m_Age<<endl;
cout<<"p3的年龄为:"<<*p3.m_Age<<endl;
}
int main(){
test01();
//int a = 10;
//int b = 20;
//int c = 30;
//c = b = a;
//cout << "a = " << a << endl;
//cout << "b = " << b << endl;
//cout << "c = " << c << endl;
return 0;
}
7-1 日程安排(多重继承+重载)
已有一个日期类Date
,包括三个protected
成员数据
int year;
int month;
int day;
另有一个时间类Time
,包括三个protected
成员数据
int hour;
int minute;
int second;
现需根据输入的日程的日期时间,安排前后顺序,为此以Date
类和Time
类为基类,建立一个日程类Schedule,包括以下新增成员:
int ID;//日程的ID
bool operator < (const Schedule & s2);//判断当前日程时间是否早于s2
生成以上类,并编写主函数,根据输入的各项日程信息,建立日程对象,找出需要最早安排的日程,并输出该日程对象的信息。
输入格式: 测试输入包含若干日程,每个日程占一行(日程编号ID 日程日期(****//*)日程时间(*::**))。当读入0时输入结束,相应的结果不要输出。
输入样例:
1 2014/06/27 08:00:01
2 2014/06/28 08:00:01
0
输出样例:
The urgent schedule is No.1: 2014/6/27 8:0:1
Code
240527
#include<bits/stdc++.h>
using namespace std;
class Date{
protected:
int year;
int month;
int day;
public:
// Date():year(1970),month(1),day(1){};
Date(int a,int b,int c):year(a),month(b),day(c){};
// bool operator<(const Date& other){
// if(this->year<other.year) return true;
// if(this->year>other.year) return false;
// if(this->month<other.month) return true;
// if(this->month>other.month) return false;
// if(this->day<other.day) return true;
// return false;
// }
// bool operator>(const Date& other){
// if(this->year>other.year) return true;
// if(this->year<other.year) return false;
// if(this->month>other.month) return true;
// if(this->month<other.month) return false;
// if(this->day>other.day) return true;
// return false;
// }
// bool operator==(const Date& other){
// if(this->year==other.year && this->month==other.month && this->day==other.day)
// return true;
// return false;
// }
};
class Time{
protected:
int hour;
int minute;
int second;
public:
// Time():hour(0),minute(0),second(0){};
Time(int a,int b,int c):hour(a),minute(b),second(c){};
// bool operator<(const Time& other){
// if(this->hour<other.hour) return true;
// if(this->hour>other.hour) return false;
// if(this->minute<other.minute) return true;
// if(this->minute>other.minute) return false;
// if(this->second<other.second) return true;
// return false;
// }
// bool operator>(const Time& other){
// if(this->hour>other.hour) return true;
// if(this->hour<other.hour) return false;
// if(this->minute>other.minute) return true;
// if(this->minute<other.minute) return false;
// if(this->second>other.second) return true;
// return false;
// }
// bool operator==(const Time& other){
// if(this->hour==other.hour && this->minute==other.minute && this->second==other.second)
// return true;
// return false;
// }
};
// class Schedule{
// friend Date;
// friend Time;
// public:
// int ID;
// Date date;
// Time time;
// Schedule(int id,int y,int month,int d,int h,int min,int s):ID(id),date(y,month,d),time(h,min,s){};
// bool operator<(const Schedule& s2){
// if(this->date<s2.date) return true;
// if(this->date>s2.date) return false;
// if(this->time<s2.time) return true;
// return false;
// }
// };
class Schedule:Date,Time{
public:
int ID;
Schedule(int id,int y,int month,int d,int h,int min,int s):Date(y,month,d),Time(h,min,s),ID(id){};
bool operator<(const Schedule& s2){
if(this->year<s2.year) return true;
if(this->year>s2.year) return false;
if(this->month<s2.month) return true;
if(this->month>s2.month) return false;
if(this->day<s2.day) return true;
if(this->day>s2.day) return false;
if(this->hour<s2.hour) return true;
if(this->hour>s2.hour) return false;
if(this->minute<s2.minute) return true;
if(this->minute>s2.minute) return false;
if(this->second<s2.second) return true;
return false;
}
void print(){
printf("The urgent schedule is No.%d: %d/%d/%d %d:%d:%d\n",ID,year,month,day,hour,minute,second);
}
};
int main(){
Schedule urgent(0,9999,0,0,0,0,0);
int id,y,month,d,h,min,s;
while(scanf("%d",&id) && id!=0){
scanf("%d/%d/%d %d:%d:%d",&y,&month,&d,&h,&min,&s);
Schedule temp(id,y,month,d,h,min,s);
if(temp<urgent) urgent=temp;
}
urgent.print();
return 0;
}
7-2 动物世界
Score 10
Author 陈晓梅
Organization 广东外语外贸大学
补充程序 :
1、实现Mammal
类的方法
2、由Mammal
类派生出Dog
类,在Dog
类中增加itsColor
成员(COLOR
类型)
3、Dog
类中增加以下方法:
constructors
:
Dog()
、Dog(int age)
、Dog(int age, int weight)
、Dog(int age, COLOR color)
、
Dog(int age, int weight, COLOR color)
、~Dog()
accessors
:
GetColor()
、SetColor()
Other methods
:
WagTail()
、BegForFood()
,并实现以上这些方法
。
提示:类似Speak()
、WagTail()
这些动作,函数体可以是输出一句话。比如:Mammal is spaeking...
, The Dog is Wagging its tail...
4、补充主函数的问号部分,并运行程序,检查输出是否合理。
enum COLOR{ WHITE, RED, BROWN, BLACK, KHAKI };
class Mammal
{
public:
//constructors
Mammal();
Mammal(int age);
~Mammal();
//accessors
int GetAge() const;
void SetAge(int);
int GetWeight() const;
void SetWeight(int);
//Other methods
void Speak() const;
void Sleep() const;
protected:
int itsAge;
int itsWeight;
};
int main()
{
Dog Fido;
Dog Rover(5);
Dog Buster(6, 8);
Dog Yorkie(3, RED);
Dog Dobbie(4, 20, KHAKI);
Fido.Speak();
Rover.WagTail();
cout << "Yorkie is " << ?? << " years old." << endl;
cout << "Dobbie weighs " << ?? << " pounds." << endl;
return 0;
}
输入格式:
无
输出格式:
按照程序格式输出。
输入样例:
在这里给出一组输入。例如:
无
输出样例:
在这里给出相应的输出。例如:
Mammal is speaking...
The dog is wagging its tail...
Yorkie is 3 years old.
Dobbie weighs 20 pounds.
Code
240527
#include<bits/stdc++.h>
using namespace std;
enum COLOR{ WHITE,RED,BROWN,BLACK,KHAKI };
class Mammal{
public:
//constructors
Mammal(){};
Mammal(int age):itsAge(age){};
Mammal(int age,int weight):itsAge(age),itsWeight(weight){};
~Mammal(){};
//accessors
int GetAge() const{
return this->itsAge;
};
void SetAge(int age){
this->itsAge=age;
};
int GetWeight() const{
return this->itsWeight;
};
void SetWeight(int weight){
this->itsWeight=weight;
};
//Other methods
void Speak() const{
cout<<"Mammal is speaking..."<<endl;
return;
};
void Sleep() const{
cout<<"Mammal is sleeping..."<<endl;
return;
};
protected:
int itsAge;
int itsWeight;
};
class Dog:public Mammal{
protected:
COLOR _color;
public:
Dog(){};
Dog(int age):Mammal(age){};
Dog(int age,int weight):Mammal(age,weight){};
Dog(int age,COLOR color):Mammal(age),_color(color){};
Dog(int age,int weight,COLOR color):Mammal(age,weight),_color(color){};
~Dog(){};
void WagTail(){
cout<<"The dog is wagging its tail..."<<endl;
}
};
int main(){
Dog Fido;
Dog Rover(5);
Dog Buster(6,8);
Dog Yorkie(3,RED);
Dog Dobbie(4,20,KHAKI);
Fido.Speak();
Rover.WagTail();
cout<<"Yorkie is "<<Yorkie.GetAge()<<" years old."<<endl;
cout<<"Dobbie weighs "<<Dobbie.GetWeight()<<" pounds."<<endl;
return 0;
}
7-3 打印点、圆、圆柱信息
定义平面二维点类CPoint
,有数据成员x
坐标,y
坐标,函数成员(构造函数、虚函数求面积GetArea
,
虚函数求体积函数GetVolume
、输出点信息函数print
)。
由CPoint
类派生出圆类Cirle
类(新增数据成员半径radius
),函数成员(构造函数、求面积GetArea
,虚函数求体积函数GetVolume
、输出圆面积信息函数print
)。
再由Ccirle
类派生出圆柱体Ccylinder
类(新增数据成员高度height
),函数成员(构造函数、求表面积GetArea
,求体积函数GetVolume
、输出圆柱体体积信息函数print
)。在主函数测试这个这三个类。
打印数据保留小数点后2位
输入格式:
点的:x坐标 点的:y坐标 圆半径 圆柱高
输出格式:
点信息 圆面积 圆柱体积
输入样例:
在这里给出一组输入。例如:
1
2
3
4
输出样例:
在这里给出相应的输出。例如:
CPoint:1,2
CirleArea:28.26
CcylinderVolume:113.04
Code
240528
#include<bits/stdc++.h>
using namespace std;
class CPoint{
protected:
int x,y;
public:
CPoint(int a,int b):x(a),y(b){};
virtual void GetArea(){};
virtual void GetVolume(){};
void print(){
printf("CPoint:%d,%d\n",x,y);
}
};
class CCircle:public CPoint{
protected:
int radius;
public:
CCircle(int a,int b,int c):CPoint(a,b),radius(c){};
void GetArea() override{
printf("CirleArea:%.2lf\n",3.14*radius*radius);
}
void GetVolume() override{};
};
class Ccylinder:public CCircle{
protected:
int height;
public:
Ccylinder(int a,int b,int c,int d):CCircle(a,b,c),height(d){};
void GetArea() override{
// printf("%.2lf\n",3.14*radius*radius*2+2*3.14*radius*height);
printf("CirleArea:%.2lf\n",3.14*radius*radius);
}
void GetVolume() override{
printf("CcylinderVolume:%.2lf\n",3.14*radius*radius*height);
}
};
int main(){
int a,b,c,d;
cin>>a>>b>>c>>d;
Ccylinder t(a,b,c,d);
t.print();
t.GetArea();
t.GetVolume();
return 0;
}
7-4 单继承中的构造函数与析构函数
编写代码实现一个表示点的父类Dot
和一个表示圆的子类Cir
,求圆的面积。
Dot
类有两个private
数据成员
float x,y;
Cir
类新增一个private
的数据成员半径float r
和一个public
的求面积的函数getArea( );
主函数已经给出,请编写Dot
和Cir
类。
#include <iostream>
#include<iomanip>
using namespace std;
const double PI=3.14;
//请编写你的代码
int main(){
float x,y,r;
cin>>x>>y>>r;
Cir c(x,y,r);
cout<<fixed<<setprecision(2)<<c.getArea()<<endl;
return 0;
}
输入格式:
输入圆心和半径,x
y
r
中间用空格分隔。
输出格式:
输出圆的面积,小数点后保留2位有效数字,注意:const double PI=3.14
,面积=PI*r*r
。
输入样例:
在这里给出一组输入。例如圆的中心点为原点(0,0)
,半径为3:
0 0 4
输出样例:
在这里给出相应的输出。例如:
Dot constructor called
Cir constructor called
50.24
Cir destructor called
Dot destructor called
Code
240528
#include<iostream>
using namespace std;
const double PI=3.14;
class Dot{
private:
float x,y;
public:
Dot(int a,int b):x(a),y(b){
cout<<"Dot constructor called"<<endl;
};
~Dot(){
cout<<"Dot destructor called"<<endl;
}
};
class Cir:public Dot{
private:
float r;
public:
Cir(int a,int b,int c):Dot(a,b),r(c){
cout<<"Cir constructor called"<<endl;
};
float getArea(){
return PI*r*r;
}
~Cir(){
cout<<"Cir destructor called"<<endl;
}
};
int main(){
int a,b,c;
cin>>a>>b>>c;
Cir t(a,b,c);
cout<<t.getArea()<<endl;
return 0;
}
7-5 定义一个Time类
定义一个时间类,能够提供和设置由时、分、秒组成的时间,并按照如下的格式输出时间:
08-09-24
12-23-59
输入格式:
请在这里写输入格式。例如: 12 8 9
8 24 59
输出格式:
请在这里描述输出格式。例如: 12-08-09
08-24-59
输入样例:
在这里给出一组输入。例如:
8 9 24
输出样例:
在这里给出相应的输出。例如:
08-09-24
Code
240528
#include<iostream>
using namespace std;
int main(){
int a,b,c;
while(scanf("%d %d %d",&a,&b,&c)!=EOF){
printf("%02d-%02d-%02d\n",a,b,c);
}
return 0;
}
7-6 绩点计算 - 《C++编程基础及应用》- 习题3-3
某大学的GPA(绩点)计算规则如下:
课程百分制成绩90分对应绩点4.0,超过90分的,按90分计;如不足90分,则课程绩点
= 4.0 * 分数/90
。
学生综合绩点按该生已修的各门课程绩点结合学分加权平均而得。
现有步步同学入学后的已修课程(共5门)成绩表如下,请编程计算其GPA。
输入格式:
第1门课程百分制分数 学分
第2门课程百分制分数 学分
第3门课程分制分数 学分
第4门课程百分制分数 学分
第5门课程百分制分数 学分
说明:百分制分数和学分均为整数。
输出格式:
请参考输出样例。其中,GPA值保留两位小数。
输入样例:
78 3
91 5
65 4
95 3
60 2
输出样例:
GPA:3.49
提示:从键盘读取输入的方法,请参考教材后续章节。
Code
240528
#include<iostream>
using namespace std;
int main(){
int a[5],b[5];
double c[5];
double a_sum=0;
int b_sum=0;
for(int i=0;i<5;i++){
scanf("%d %d",&a[i],&b[i]);
if(a[i]>90) a[i]=90;
c[i]=4.0*a[i]/90;
b_sum+=b[i];
a_sum+=c[i]*b[i];
}
printf("GPA:%.2lf\n",a_sum/b_sum);
return 0;
}
7-7 菲姐游泳 - 《C++编程基础及应用》- 习题3-5
游泳奥运冠军菲姐刻苦训练,从早上a时b分开始下水训练,直到当天的c时d分结束。请编程计算:菲姐当天一共训练多少小时多少分钟?
输入格式:
一行之内输入以空格分隔的4个非负整数,分别对应a,b,c,d。其中,0 ≤a<c ≤24;b和d均不大于60。
输出格式:
h:m。其中,整数h表示小时数,整数m表示分钟数,m应小于60。
输入样例:
6 30 23 20
输出样例:
16:50
Code
240528
#include<iostream>
using namespace std;
int main(){
int a,b,c,d;
cin>>a>>b>>c>>d;
c-=a;
d-=b;
if(d<0){
d+=60;
c--;
}
printf("%d:%d\n",c,d);
return 0;
}