【PTA/C++】继承与派生

程序填空题

R5-1

阅读下面的程序,完成其中复制构造函数的代码


#include 
using namespace std;
class CAT
{     public:
           CAT();
           CAT(const CAT&);
          ~CAT();
          int GetAge() const { return *itsAge; }
          void SetAge(int age){ *itsAge=age; }
      protected:
          int* itsAge;
};
CAT::CAT()
{    itsAge=new int;
     *itsAge =5;
}
CAT::CAT(const CAT& c)
{
itsAge = new int;//1
*itsAge = *c.itsAge;//2
}
CAT::~CAT()
{     delete itsAge;   }

R5-2

下面程序的输出结果是:

A::Fun

A::Do

A::Fun

C::Do

填空使程序完整。

#include
using namespace std;
class A{
private:
    int val;
public:
    void Fun()
    {
        cout<<"A::Fun"<Fun();
     p->Do(); 
} 

int main(){ 
    Call(new A());
    Call(new C());//2

    return 0; 
}

函数题 

R6-1.1 使用类输出图形信息

声明一个图形基类 Shape,在它的基础上派生出矩形类 Rectangle 和圆形类 Circle,他们都有计算面积和周长、输出图形信息等成员函数,再在 Rectangle 类的基础上派生出正方形类 Square。编写程序完成各类的定义和实现,以及类的使用。
注意:
题目中定义的所有数值类型的变量都使用 double 类型
π的值为 3.14159

测试程序样例:

#include  
#define PI 3.14159
using namespace std;

class Shape{
public:
    double getArea(){return 0;}
    double getPerimeter(){return 0;}
};

class Rectangle:public Shape {
protected:
    double  height;
    double  width;
public:
    Rectangle() {};
    Rectangle(double _height, double _width) {
        height = _height;
        width = _width;
    }
    double getArea(){
        return  height * width;
    }
    double getPerimeter(){
        return  2 * (height + width);
    }
    void Print(){
        cout << "Width=" << width << ",Height=" << height << endl;
    }
};
/* 请在这里填写答案 */
int  main()  {
    double  ra,  rb;
    cin  >>  ra  >>  rb;
    Rectangle  r1(ra,  rb);
    double  sa;
    cin  >>  sa;
    Square  s1(sa);
    double  ca,  cb,  cc;
    cin  >>  ca  >>  cb  >>  cc;
    Circle  c1(ca,  cb,  cc);
    cout  <<  "Rectangle"  <<  endl;
    r1.Print();
    cout  <<  "Area="  <<  r1.getArea()  <<  endl;
    cout  <<  "Perimeter="  <<  r1.getPerimeter()  <<  endl  ;
    cout  <<  "Square"  <<  endl;
    s1.Print();
    cout  <<  "Area="  <<  s1.getArea()  <<  endl;
    cout  <<  "Perimeter="  <<  s1.getPerimeter()  <<  endl;
    cout  <<  "Circle"  <<  endl;
    c1.Print();
    cout  <<  "Area="  <<  c1.getArea()  <<  endl;
    cout  <<  "Perimeter="  <<  c1.getPerimeter()  <<  endl;
    return  0;
}

输入样例:

在这里给出一组输入。例如:

4 2.5
8
4 5 6.5

输出样例:

Rectangle
Width=2.5,Height=4
Area=10
Perimeter=13
Square
Side=8
Area=64
Perimeter=32
Circle
Center=[4,5],Adius=6.5
Area=132.732
Perimeter=40.8407

提示

需要补充的类定义如下:

class Square:public Rectangle{
   //......
};
class Circle: public Shape{
     //......
};

AC:

class Square: public Rectangle {
public:
    Square(double side) : Rectangle(side, side) {}
    void Print() {
        cout << "Side=" << width << endl;
    }
};

class Circle: public Shape {
private:
    double x, y, radius;
public:
    Circle(double a, double b, double r) : x(a), y(b), radius(r) {}
    double getArea() {
        return PI * radius * radius;
    }
    double getPerimeter() {
        return 2 * PI * radius;
    }
    void Print() {
        cout << "Center=[" << x << "," << y << "],Adius=" << radius << endl;
    }
};

R6-1.2 长方形

如下,现已有一个完整的长方形的类Rectangle, 数据成员有长和宽,成员函数包括一个构造函数和一个计算面积的函数area()。

请写出一个表示长方体的派生类Box,继承这个已给出的Rectangle类,满足以下要求:

(1)只能新增一个数据成员:height (高)。

(2)定义一个合适的Box类构造函数,使得main函数中创建对象的初始化可行;

(3)使用合适的继承方式,使得main函数中能通过派生类Box对象直接调用基类中的area()函数输出底面积。

(4)新增一个成员函数 volume() 返回长方体的体积,使得main函数中的调用可行;

函数接口定义:

见题目描述

裁判测试程序样例:

#include 
using namespace std;

class Rectangle { //长方形
    public:
        Rectangle(double l, double w) : length(l), width(w) {
        }
        double area() {
            return length * width;
        }
    private:
        double length; //长
        double width; //宽
};

//在此定义派生类Box
/* 请在这里填写答案 */

int main() {
    Box b1(10, 20, 30);
    cout << b1.area() << endl;
    cout << b1.volume() << endl;
    return 0;
}

输入样例:

输出样例:

200
6000

AC:

class Box : public Rectangle {
private:
    double height;
public:
    Box(double l, double w, double h) : Rectangle(l, w), height(h) {}
    double volume() {
        return area() * height;
    }
};

 

R6-2.1 小狗

完成两个类,一个类Animal,表示动物类,有一个成员表示年龄。一个类Dog,继承自Animal,有一个新的数据成员表示颜色,合理设计这两个类,使得测试程序可以运行并得到正确的结果。

函数接口定义:

按照要求实现类

裁判测试程序样例:

/* 请在这里填写答案 */

int main(){
    Animal ani(5);
    cout<<"age of ani:"<

输入样例:

输出样例:

age of ani:5
infor of dog:
age:5
color:black

 AC:

#include 
#include 
using namespace std;

class Animal {
private:
    int age;
public:
    Animal(int a) : age(a) {}
    int getAge() const { return age; }
};

class Dog : public Animal {
private:
    string color;
public:
    Dog(int a, string c) : Animal(a), color(c) {}
    void showInfor() {
        cout << "age:" << getAge() << endl;
        cout << "color:" << color << endl;
    }
};

R6-2.2 超级魔法猫咪(内嵌对象、重写成员函数)

在神奇的猫咪王国,有一种基础类型的猫咪叫“普通猫咪”,后来,有一种“超级魔法猫咪”,这种猫咪不仅继承了“普通猫咪”的特性,还拥有一个特殊的魔法伙伴——“小精灵”。小精灵能够协助“超级魔法猫咪”施展更强大的魔法。请编写“小精灵”Fairy类、“超级魔法猫咪”SuperMagicCat类。

  • “普通猫咪”:OrdinaryCat类中 getName 返回猫的名字,getLevel 返回猫的等级,getHp 返回猫的血量(等级*100)。

  • “小精灵”:Fairy类提供成员函数 getLevel 用于获取小精灵的等级,getAbility 用于获取小精灵的能力描述,getHp 返回血量(等级*50)。

  • “超级魔法猫咪”: SuperMagicCat类继承自OrdinaryCat类,提供成员函数 getSpecialSkill,用于获取特殊技能描述,提供成员函数 getFairy ,返回小精灵对象的引用;“超级魔法猫咪”血量的计算方法为:等级*200。

裁判测试程序样例:

#include 
#include 

using namespace std;

// 普通猫
class OrdinaryCat {
protected:
    string m_name; // 猫名
    int m_level; // 等级
public:
    OrdinaryCat(const string &name, int level)
        : m_name(name), m_level(level) {}
    string getName() const { return m_name; }
    int getHp() const { return m_level * 100; }
    int getLevel() const { return m_level; }
};

// 请将答案填写在这里

int main() {
    string name, specialSkill, fairyAbility;
    int level, fairyLevel;
    // 输入: 名称 等级 特殊技能 小精灵等级 小精灵能力
    cin >> name >> level >> specialSkill >> fairyLevel >> fairyAbility;
    SuperMagicCat cat(name, level, specialSkill, fairyLevel, fairyAbility);
    cout << cat.getName() << " " << cat.getHp() << " " << cat.getSpecialSkill()
         << " " << cat.getFairy().getHp() << " " << cat.getFairy().getAbility() << endl;
    return 0;
}

输入样例:

在这里给出一组输入。例如:
超级魔法猫咪的名称是Tom、等级为6级、特殊技能是雷霆之爪,超级魔法猫咪的小精灵等级为5级、能力是治疗术

Tom 6 ThunderClaw 5 Cure

输出样例:

在这里给出相应的输出。例如:

Tom 1200 ThunderClaw 250 Cure

AC:

class Fairy {
private:
    int level;
    string ability;
public:
    Fairy(int lv, const string& ab) : level(lv), ability(ab) {}
    int getLevel() const { return level; }
    string getAbility() const { return ability; }
    int getHp() const { return level * 50; }
};

class SuperMagicCat : public OrdinaryCat {
private:
    string specialSkill;
    Fairy fairy;
public:
    SuperMagicCat(const string &name, int level, const string &skill, int fairyLevel, const string &fairyAbility)
        : OrdinaryCat(name, level), specialSkill(skill), fairy(fairyLevel, fairyAbility) {}
    string getSpecialSkill() const { return specialSkill; }
    Fairy& getFairy() { return fairy; }
    int getHp() const { return m_level * 200; }
};

R6-3 多重继承

声明一个教师(Teacher)类和一个学生(Student)类,用多重继承的方式声明一个研究生(Graduate)派生类。教师类中包括数据成员name(姓名),age(年龄),title(职称)。学生类中包括数据成员name(姓名),age(年龄),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

AC:

#include 
#include 
using namespace std;

class Teacher {
private:
    string name;
    int age;
    string title;
public:
    Teacher(string n, int a, string t) : name(n), age(a), title(t) {}
    string getName() const { return name; }
    int getAge() const { return age; }
    string getTitle() const { return title; }
};

class Student {
private:
    string name;
    int age;
    double score;
public:
    Student(string n, int a, double s) : name(n), age(a), score(s) {}
    string getName() const { return name; }
    int getAge() const { return age; }
    double getScore() const { return score; }
};

class Graduate : public Teacher, public Student {
private:
    char sex;
    double wages;
public:
    Graduate(string n, int a, char s, string t, double sc, double w)
        : Teacher(n, a, t), Student(n, a, sc), sex(s), wages(w) {}
    void show() {
        cout << "name:" << Teacher::getName() << endl;
        cout << "age:" << Teacher::getAge() << endl;
        cout << "sex:" << sex << endl;
        cout << "score:" << Student::getScore() << endl;
        cout << "title:" << getTitle() << endl;
        cout << "wages:" << wages << endl;
    }
};

编程题

R7-1.1 点的派生

设计一个名为Point的点类和一个名为Rectangle的矩形类。点类的属性是整型的x和y坐标。矩形类是从点类派生的,点坐标为矩形的左下角的点坐标,并增加两个整型属性,分别是长(X方向)和高(Y方向)。同时还有获取(并计算)右上角点的成员函数getRightUpPoint()。要求设计实现这两个类,并且矩形类还要实现带参数的构造函数,以及拷贝构造函数。从输入读取数据构造一个矩形对象R1,使用拷贝构造函数构造矩形对象变量名为R2,进而调用R2的getRightUpPoint()得到右上角坐标,然后输出该坐标值。
注意:必须按照描述要求书写代码,否则不给分。

输入格式:

输入有两行,第一行两个整数x1,y1表示矩形的左下角坐标(x1,y1);第二行两个整数lenght,width表示矩形的长(X方向)和高(Y方向)

输出格式:

输出有一行,是调用R2的getRightUpPoint()而得到的点的坐标值。

输入样例:

12 13
34 45 

输出样例:

46 58

AC:

#include 
using namespace std;

class Point {
private:
    int x;
    int y;
public:
    Point(int x = 0, int y = 0) : x(x), y(y) {}  // 带默认参数的构造函数
    Point(const Point& p) : x(p.x), y(p.y) {}     // 拷贝构造函数
    int getX() const { return x; }                // 新增获取x坐标的接口
    int getY() const { return y; }                // 新增获取y坐标的接口
};

class Rectangle : public Point {  // 修正继承语法
private:                         // 补充冒号
    int length;
    int height;
public:
    // 带参构造函数
    Rectangle(int x, int y, int l, int h) : Point(x, y), length(l), height(h) {}
    
    // 拷贝构造函数
    Rectangle(const Rectangle& other) 
        : Point(other.getX(), other.getY()),  // 调用基类拷贝构造
          length(other.length), 
          height(other.height) {}
    
    // 获取右上角坐标
    Point getRightUpPoint() const {
        return Point(getX() + length, getY() + height);
    }
};

int main() {
    int x, y, l, h;
    // 读取输入(第一行坐标,第二行长高)
    cin >> x >> y;
    cin >> l >> h;
    
    // 创建对象
    Rectangle R1(x, y, l, h);  // 带参构造
    Rectangle R2(R1);          // 拷贝构造
    
    // 获取并输出右上角坐标
    Point p = R2.getRightUpPoint();
    cout << p.getX() << " " << p.getY();
    
    return 0;
}

R7-1.2 定义基类Point和派生类Circle,求圆的周长.

定义基类Point(点)和派生类Circle(圆),求圆的周长。Point类有两个私有的数据成员float x,y;Circle类新增一个私有的数据成员半径float r和一个公有的求周长的函数getCircumference();主函数已经给出,请编写Point和Circle类。

#include 
#include
using namespace std;
//请编写你的代码
int main()
{
    float x,y,r;
    cin>>x>>y>>r;
    Circle c(x,y,r);
    cout<

输入格式:

输入圆心和半径,x y r中间用空格分隔。

输出格式:

输出圆的周长,小数点后保留2位有效数字。

输入样例:

1 2 3

输出样例:

在这里给出相应的输出。例如:

Point constructor called
Circle constructor called
18.84
Circle destructor called
Point destructor called

AC:

#include 
#include 
using namespace std;
const double PI = 3.14;

class Point {
private:
    float x, y;
public:
    Point(float a, float b) : x(a), y(b) {
        cout << "Point constructor called" << endl;
    }
    ~Point() {
        cout << "Point destructor called" << endl;
    }
};

class Circle : public Point {
private:
    float r;
public:
    Circle(float a, float b, float radius) : Point(a, b), r(radius) {
        cout << "Circle constructor called" << endl;
    }
    ~Circle() {
        cout << "Circle destructor called" << endl;
    }
    double getCircumference() const {
        return 2 * PI * r;
    }
};

int main()
{
    float x,y,r;
    cin>>x>>y>>r;
    Circle c(x,y,r);
    cout<

 

R7-1.3 两点间距离计算

给出下面的一个基类框架:

class Point_1D

{ protected:

    float x;//1D 点的x坐标

public:

    Point_1D(float p = 0.0);

    float distance(const Point_1D & p2);

}

以Point_1D为基类建立一个派生类Point_2D,增加一个保护数据成员:

    float y;//2D平面上点的y坐标

以Point_2D为直接基类再建立一个派生类Point_3D,增加一个保护数据成员:

    float z;//3D立体空间中点的z坐标

生成上述类并编写主函数,根据输入的点的基本信息,建立点对象,并能计算该点到原点的距离。

输入格式: 测试输入包含若干测试用例,每个测试用例占一行(点的类型(1表示1D点,2表示2D点,3表示3D点) 第一个点坐标信息(与点的类型相关) 第二个点坐标信息(与点的类型相关))。当读入0时输入结束,相应的结果不要输出。

输入样例:

1 -1 0

2 3 4 0 0

3 1 2 2 0 0 0

0

输出样例:

Distance from Point -1 to Point 0 is 1

Distance from Point(3,4) to Point(0,0) is 5

Distance from Point(3,3,3) to Point(0,0,0) is 3

AC:

#include 
#include 
using namespace std;

// 1D 点类
class Point_1D {
protected:
    float x; // 1D 点的 x 坐标
public:
    Point_1D(float p = 0.0) : x(p) {}
    float distance(const Point_1D &p2) {
        return abs(x - p2.x);
    }
    float getX() const {
        return x;
    }
};

// 2D 点类
class Point_2D : public Point_1D {
protected:
    float y; // 2D 平面上点的 y 坐标
public:
    Point_2D(float p1 = 0.0, float p2 = 0.0) : Point_1D(p1), y(p2) {}
    float distance(const Point_2D &p2) {
        return sqrt(pow(x - p2.x, 2) + pow(y - p2.y, 2));
    }
    float getY() const {
        return y;
    }
};

// 3D 点类
class Point_3D : public Point_2D {
protected:
    float z; // 3D 立体空间中点的 z 坐标
public:
    Point_3D(float p1 = 0.0, float p2 = 0.0, float p3 = 0.0) : Point_2D(p1, p2), z(p3) {}
    float distance(const Point_3D &p2) {
        return sqrt(pow(x - p2.x, 2) + pow(y - p2.y, 2) + pow(z - p2.z, 2));
    }
    float getZ() const {
        return z;
    }
};

int main() {
    int type;
    while (cin >> type && type != 0) {
        if (type == 1) {
            float x1, x2;
            cin >> x1 >> x2;
            Point_1D p1(x1), p2(x2);
            cout << "Distance from Point " << x1 << " to Point " << x2 << " is " << p1.distance(p2) << endl;
        } else if (type == 2) {
            float x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            Point_2D p1(x1, y1), p2(x2, y2);
            cout << "Distance from Point(" << x1 << "," << y1 << ") to Point(" << x2 << "," << y2 << ") is " << p1.distance(p2) << endl;
        } else if (type == 3) {
            float x1, y1, z1, x2, y2, z2;
            cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
            Point_3D p1(x1, y1, z1), p2(x2, y2, z2);
            cout << "Distance from Point(" << x1 << "," << y1 << "," << z1 << ") to Point(" << x2 << "," << y2 << "," << z2 << ") is " << p1.distance(p2) << endl;
        }
    }
    return 0;
}    

R7-2.1 学生CPP成绩计算

给出下面的人员基类框架:

class Person
    {

    protected:
    string name;
    int age;
    public:
    Person();      
    Person (string p_name, int p_age);
    void display () {cout<

建立一个派生类student,增加以下成员数据:

int ID;//学号
float cpp_score;//cpp上机成绩
float cpp_count;//cpp上机考勤
float cpp_grade;//cpp总评成绩
     //总评成绩计算规则:cpp_grade = cpp_score * 0.9 + cpp_count * 2;

增加以下成员函数:

student类的无参构造函数

student类的参数化构造函数//注意cpp_grade为上机成绩和考勤的计算结果

void print()//输出当前student的信息

student类的无参构造函数

student类的参数化构造函数//注意cpp_grade为上机成绩和考勤的计算结果

void print()//输出当前student的信息    
             //其中cpp_grade输出保留一位小数
                //输出格式为ID name cpp_grade

生成上述类并编写主函数,根据输入的学生基本信息,建立一个学生对象,计算其cpp总评成绩,并输出其学号、姓名、总评成绩。

输入格式: 测试输入包含若干测试用例,每个测试用例占一行(学生姓名 学号 年龄 cpp成绩 cpp考勤)。当读入0时输入结束,相应的结果不要输出。

输入样例:

Bob 10001 18 75.5 4

Mike 10005 17 95.0 5

0

输出样例:

10001 Bob 75.9

10005 Mike 95.5

AC:

#include 
#include 
#include 

using namespace std;

class Person {
protected:
    string name;
    int age;
public:
    Person() : name(""), age(0) {}
    Person(string p_name, int p_age) : name(p_name), age(p_age) {}
    void display() { cout << name << ":" << age << endl; }
};

class student : public Person {
protected:
    int ID;
    float cpp_score;
    float cpp_count;
    float cpp_grade;
public:
    student() : ID(0), cpp_score(0), cpp_count(0), cpp_grade(0) {}
    student(string p_name, int p_id, int p_age, float score, float count)
        : Person(p_name, p_age), ID(p_id), cpp_score(score), cpp_count(count) {
        cpp_grade = cpp_score * 0.9 + cpp_count * 2;
    }
    void print() {
        cout << ID << " " << name << " " << fixed << setprecision(1) << cpp_grade << endl;
    }
};

int main() {
    string name;
    while (cin >> name) {
        if (name == "0") {
            break;
        }
        int id, age;
        float score, count;
        cin >> id >> age >> score >> count;
        student stu(name, id, age, score, count);
        stu.print();
    }
    return 0;
}

R7-2.2 学生cpp成绩统计

完成“学生cpp成绩计算”之后,修改Person和Student类,各自增加两个无参构造函数。

仍以Person类为基础,建立一个派生类Teacher,增加以下成员数据:

   int ID;//教师工号
   Student stu[100];//学生数组
   int count;//学生数目,最多不超过100
   float cpp_average;//班级cpp平均分

增加以下成员函数:

  Teacher类的参数化构造函数
  void Add (Student & stu1)//在学生数组中增加一个学生记录
  void average();//计算当前班级cpp平均成绩cpp_average
  void print()//输出当前班级学生的信息
           //其中学生记录中cpp_score和cpp_grade输出保留一位小数
                  //当前班级cpp_average输出保留一位小数;
                  //输出格式如下:
             //第一行:教师工号 教师姓名 班级学生数 cpp_average
       //第二行至第count+1行每一行输出一个学生的信息,每一行格式
      // 学生学号 学生姓名 cpp_grade
     //cpp_grade保留一位小数

生成上述类并编写主函数,根据输入的教师基本信息,建立一个教师对象,根据输入的每一条学生基本信息,建立一个学生对象,计算学生cpp总评成绩并且加入学生数组中,由教师对象计算班级cpp平均成绩,并输出班级学生的全部信息。

输入格式: 测试输入包含一个测试用例,该测试用例的第一行输入教师的基本信息(教师姓名 教师工号 年龄),第二行开始输入班级内学生信息,每个学生基本信息占一行(学生姓名 学号 年龄 cpp成绩 cpp考勤),最多不超过100行,当读入0时输入结束。

输入样例:

Mike 901 30

Bob 10001 18 75.9 4

Anna 10003 19 87.0 5

0

输出样例:

901 Michale 2 82.3

10001 Bob 76.3

10003 Anna 88.3

AC:

#include 
#include 
#include 
using namespace std;

// Person 类
class Person {
protected:
    string name;
    int age;
public:
    Person() : name(""), age(0) {}
    Person(string n, int a) : name(n), age(a) {}
};

// Student 类
class Student : public Person {
protected:
    string id;
    float cpp_score;
    int cpp_attendance;
    float cpp_grade;
public:
    Student() : Person(), id(""), cpp_score(0.0), cpp_attendance(0), cpp_grade(0.0) {}
    Student(string n, string i, int a, float s, int att) : Person(n, a), id(i), cpp_score(s), cpp_attendance(att) {
        cpp_grade = cpp_score + cpp_attendance;
    }
    string getID() const {
        return id;
    }
    string getName() const {
        return name;
    }
    float getCppGrade() const {
        return cpp_grade;
    }
};

// Teacher 类
class Teacher : public Person {
private:
    int ID;
    Student stu[100];
    int count;
    float cpp_average;
public:
    Teacher(string n, int id, int a) : Person(n, a), ID(id), count(0), cpp_average(0.0) {}
    void Add(Student &stu1) {
        stu[count++] = stu1;
    }
    void average() {
        float sum = 0.0;
        for (int i = 0; i < count; ++i) {
            sum += stu[i].getCppGrade();
        }
        cpp_average = sum / count;
    }
    void print() {
        cout << fixed << setprecision(1);
        cout << ID << " " << name << " " << count << " " << cpp_average << endl;
        for (int i = 0; i < count; ++i) {
            cout << stu[i].getID() << " " << stu[i].getName() << " " << stu[i].getCppGrade() << endl;
        }
    }
};

int main() {
    string teacherName;
    int teacherID, teacherAge;
    cin >> teacherName >> teacherID >> teacherAge;
    Teacher teacher(teacherName, teacherID, teacherAge);

    string studentName, studentID;
    int studentAge, cppAttendance;
    float cppScore;
    while (cin >> studentName && studentName != "0") {
        cin >> studentID >> studentAge >> cppScore >> cppAttendance;
        Student student(studentName, studentID, studentAge, cppScore, cppAttendance);
        teacher.Add(student);
    }

    teacher.average();
    teacher.print();

    return 0;
}    

R7-3 A是A1的虚基类

本题目要求读入3个整数A、B和C,然后按照下列要求完成相关设计:1.定义一个基类A,在其中包含保护的数据成员int i,设计类A的带参构造函数对i进行初始化,定义成员函数display()显示i值; 2.定义基类A的公有派生类A1,且A是A1的虚基类;A1中包含保护的数据成员int j,设计类A1的构造函数; 3.定义基类A的公有派生类A2,且A是A2的虚基类;A2中包含保护的数据成员int k,设计类A2的构造函数; 4.定义类A3,A3是A1和A2以多继承方式生成的公有派生类,设计类A3的构造函数;定义成员函数disp()在其中调用display()函数显示i值,另外输出j和k值; 5.在main()中定义类A3的1个对象变量,通过输入的3个整数完成对象的创建;调用类A3的成员函数disp()输出信息。

输入格式:

输入在一行中给出3个绝对值不超过1000的整数A、B和C。

输出格式:

按行输出每个类中的构造函数中的信息和在主函数中调用的对象的成员函数。

输入样例:

在这里给出一组输入。例如:

1 2 3

输出样例:

在这里给出相应的输出。例如:

Call A:i=1
Call A1:i=1
Call A2:i=1
Call A3:i=1
i=1
j=2
k=3

AC:

#include 
using namespace std;

class A {
protected:
    int i;
public:
    A(int a) : i(a) {
        cout << "Call A:i=" << i << endl;
    }
    void display() {
        cout << "i=" << i << endl;
    }
};

class A1 : virtual public A {
protected:
    int j;
public:
    A1(int a, int b) : A(a), j(b) {
        cout << "Call A1:i=" << i << endl;
    }
};

class A2 : virtual public A {
protected:
    int k;
public:
    A2(int a, int c) : A(a), k(c) {
        cout << "Call A2:i=" << i << endl;
    }
};

class A3 : public A1, public A2 {
public:
    A3(int a, int b, int c) : A(a), A1(a, b), A2(a, c) {
        cout << "Call A3:i=" << i << endl;
    }
    void disp() {
        display();
        cout << "j=" << j << endl;
        cout << "k=" << k << endl;
    }
};

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    A3 obj(a, b, c);
    obj.disp();
    return 0;
}

R7-4 车辆选择(继承)

有一个汽车类vehicle,它具有一个需传递参数的构造函数,汽车类vehicle中的数据成员为:
车轮个数wheels和车重weight放在保护段中,汽车类vehicle中的公有成员函数为:get_wheels()(返回车轮个数的值)、get_weight()(返回车重的值)、wheel_load()(返回每个轮胎的载重量的值:weight/wheels)、print()(输出车轮的个数和车重的公斤数);

小车类car是vehicle类的派生类,它具有一个需传递参数的构造函数,小车类car中的私有数据成员为:车载人数passenger_load,小车类car中的公有成员函数为:get_passengers()(返回车载人数的值)、print()(输出小车车轮的个数和车重的公斤数以及车载人数的个数);

卡车类truck是vehicle类的派生类,它具有一个需传递参数的构造函数,卡车类truck中的私有数据成员为:载人数passenger_load和载重量payload,卡车类truck中的公有成员函数为:get_passengers()(返回车载人数的值)、efficiency()(返回卡车的载重效率的值:payload/(payload+weight)、print()(输出卡车车轮的个数和车重的公斤数以及车载人数的个数和卡车的载重效率的值))。

生成上述类并编写主函数,根据输入的车辆基本信息,建立车辆对象,并能计算输出该车辆的基本信息。
输入格式:测试输入包含一个测试用例,每一行给出一个车辆的基本信息,每行的第一个字符处为当前车辆的类型,第二个数字为当前车辆的编号,若车辆为vehicle,后面跟随两个数字分别为wheels和weight,若车辆为car,后面跟随三个数字分别为wheels,weight和车载人数,若车辆为truck,后面跟随四个数字分别是wheels,weight、车载人数和载重量。(以上数字均为整型)。-1表示输入结束,相应结果不要输出。请注意输出格式,按照输入顺序进行编号
说明:本题中轮胎载重量、载重效率若需输出保留小数点后两位。

输入样例:

vehicle 101 4 1900

car 201 4 2000 5

truck 301 6 3000 2 9000

car 202 4 1800 4

-1

输出样例:

The 1st object is Vehicle No. 101: weight 1900 Kg and wheels 4

The 2nd object is Car No. 201: passenger_load 5 weight 2000 Kg and wheels 4

The 3rd object is Truck No. 301: passenger_load 2 weight 3000 Kg wheels 6 and efficiency 0.75

The 4th object is Car No. 202: passenger_load 4 weight 1800 Kg and wheels 4

AC:

#include 
#include 
#include 
using namespace std;

class Vehicle {
protected:
    int id;
    int wheels;
    int weight;

public:
    Vehicle(int i, int w, int wt) : id(i), wheels(w), weight(wt) {}

    virtual void print(int index) {
        string suffix;
        if (index % 100 >= 11 && index % 100 <= 13) {
            suffix = "th";
        } else {
            switch (index % 10) {
                case 1: suffix = "st"; break;
                case 2: suffix = "nd"; break;
                case 3: suffix = "rd"; break;
                default: suffix = "th"; break;
            }
        }
        cout << "The " << index << suffix << " object is Vehicle No. " << id 
             << ": weight " << weight << " Kg and wheels " << wheels << endl;
    }
};

class Car : public Vehicle {
private:
    int passenger_load;

public:
    Car(int i, int w, int wt, int p) : Vehicle(i, w, wt), passenger_load(p) {}

    void print(int index) override {
        string suffix;
        if (index % 100 >= 11 && index % 100 <= 13) {
            suffix = "th";
        } else {
            switch (index % 10) {
                case 1: suffix = "st"; break;
                case 2: suffix = "nd"; break;
                case 3: suffix = "rd"; break;
                default: suffix = "th"; break;
            }
        }
        cout << "The " << index << suffix << " object is Car No. " << id 
             << ": passenger_load " << passenger_load << " weight " << weight 
             << " Kg and wheels " << wheels << endl;
    }
};

class Truck : public Vehicle {
private:
    int passenger_load;
    int payload;

public:
    Truck(int i, int w, int wt, int p, int pl) : Vehicle(i, w, wt), passenger_load(p), payload(pl) {}

    double efficiency() {
        return static_cast(payload) / (payload + weight);
    }

    void print(int index) override {
        string suffix;
        if (index % 100 >= 11 && index % 100 <= 13) {
            suffix = "th";
        } else {
            switch (index % 10) {
                case 1: suffix = "st"; break;
                case 2: suffix = "nd"; break;
                case 3: suffix = "rd"; break;
                default: suffix = "th"; break;
            }
        }
        cout << "The " << index << suffix << " object is Truck No. " << id 
             << ": passenger_load " << passenger_load << " weight " << weight 
             << " Kg wheels " << wheels << " and efficiency " 
             << fixed << setprecision(2) << efficiency() << endl;
    }
};

int main() {
    vector vehicles;
    string type;
    int index = 0;

    while (cin >> type) {
        if (type == "-1") break;
        index++;
        int id, wheels, weight, passenger_load, payload;

        if (type == "vehicle") {
            cin >> id >> wheels >> weight;
            vehicles.push_back(new Vehicle(id, wheels, weight));
        } else if (type == "car") {
            cin >> id >> wheels >> weight >> passenger_load;
            vehicles.push_back(new Car(id, wheels, weight, passenger_load));
        } else if (type == "truck") {
            cin >> id >> wheels >> weight >> passenger_load >> payload;
            vehicles.push_back(new Truck(id, wheels, weight, passenger_load, payload));
        }
    }

    for (int i = 0; i < vehicles.size(); i++) {
        vehicles[i]->print(i + 1);
    }

    // 释放内存
    for (auto veh : vehicles) {
        delete veh;
    }

    return 0;
}

R7-5 动物世界

补充程序 :

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.

AC:

#include 
using namespace std;

enum COLOR { WHITE, RED, BROWN, BLACK, KHAKI };

class Mammal {
public:
    Mammal() : itsAge(0), itsWeight(0) {}
    Mammal(int age) : itsAge(age), itsWeight(0) {}
    ~Mammal() {}
    int GetAge() const { return itsAge; }
    void SetAge(int age) { itsAge = age; }
    int GetWeight() const { return itsWeight; }
    void SetWeight(int weight) { itsWeight = weight; }
    void Speak() const { cout << "Mammal is speaking..." << endl; }
    void Sleep() const { cout << "Mammal is sleeping..." << endl; }
protected:
    int itsAge;
    int itsWeight;
};

class Dog : public Mammal {
private:
    COLOR itsColor;
public:
    Dog() : Mammal(), itsColor(WHITE) {}
    Dog(int age) : Mammal(age), itsColor(WHITE) {}
    Dog(int age, int weight) : Mammal(age) { itsWeight = weight; itsColor = WHITE; }
    Dog(int age, COLOR color) : Mammal(age), itsColor(color) {}
    Dog(int age, int weight, COLOR color) : Mammal(age) { itsWeight = weight; itsColor = color; }
    ~Dog() {}
    COLOR GetColor() const { return itsColor; }
    void SetColor(COLOR color) { itsColor = color; }
    void WagTail() const { cout << "The dog is wagging its tail..." << endl; }
    void BegForFood() const { cout << "The dog is begging for food..." << 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;
}

R7-6.1 时间模拟

给出下面的基类Time的框架如下:

class Time

{
protected:

    int second;
    int minute;
    int hour;

public:

     void operator++();
     void operator--();

}

建立一个派生类Time_12hours,用于表示十二进制时间,增加以下成员数据:

string type;//标识为12进制时间,type=”12-hours-time”

string interval;//标识为AM或者PM,interval=”AM”或interval=”PM”

增加以下成员函数:
void operator++();

     void operator--();

建立一个派生类Time_24hours,用于表示二十四进制时间,增加以下成员数据:

     string type;//标识为24进制时间,type=”24-hours-time”

增加以下成员函数:

     void operator++();

     void operator--();

生成上述类并编写主函数,根据输入的初始时间信息、自增或者自减类型、自增或者自减次数,输出其最后时间信息。

输入格式:测试输入包含多个测试用例,一个测试用例为一行,每行共五个数字,第一个数字为进制,121表示输入为12进制AM时间,122表示输入为12进制PM时间,输入为24表示输入为24进制时间,第二个数字为hour,第三个数字为minute,第四个数字为second,第五个字符为运算类型,+表示自增,-表示自减,第六个数字为运算次数,0表示测试用例结束。

输入样例:

121 11 59 59 + 3

24 11 59 59 + 3

122 11 59 59 + 3

122 00 00 00 - 3

121 00 00 00 - 5

24 00 00 00 - 1

0

输出样例:

PM 00:00:02

12:00:02

AM 00:00:02

AM 11:59:57

PM 11:59:55

AC:

#include 
#include 
using namespace std;

class Time {
protected:
    int second;
    int minute;
    int hour;

public:
    Time() : hour(0), minute(0), second(0) {}
    Time(int h, int m, int s) : hour(h), minute(m), second(s) {}
    void operator++() {}
    void operator--() {}
};

class Time_12hours : public Time {
private:
    string interval;

public:
    Time_12hours(int type, int h, int m, int s) {
        interval = (type == 121) ? "AM" : "PM";
        hour = h;
        minute = m;
        second = s;
        if (hour == 12) hour = 0; // 12转换为0
    }

    void operator++() {
        ++second;
        if (second >= 60) {
            second = 0;
            ++minute;
            if (minute >= 60) {
                minute = 0;
                ++hour;
                if (hour == 12) {
                    interval = (interval == "AM") ? "PM" : "AM";
                    hour = 0;
                }
            }
        }
    }

    void operator--() {
        --second;
        if (second < 0) {
            second = 59;
            --minute;
            if (minute < 0) {
                minute = 59;
                --hour;
                if (hour < 0) {
                    hour = 11;
                    interval = (interval == "AM") ? "PM" : "AM";
                }
            }
        }
    }

    void print() const {
        cout << interval << " " << setfill('0')
             << setw(2) << hour << ":" 
             << setw(2) << minute << ":" 
             << setw(2) << second << endl;
    }
};

class Time_24hours : public Time {
public:
    Time_24hours(int h, int m, int s) : Time(h, m, s) {}

    void operator++() {
        ++second;
        if (second >= 60) {
            second = 0;
            ++minute;
            if (minute >= 60) {
                minute = 0;
                ++hour;
                if (hour >= 24) hour = 0;
            }
        }
    }

    void operator--() {
        --second;
        if (second < 0) {
            second = 59;
            --minute;
            if (minute < 0) {
                minute = 59;
                --hour;
                if (hour < 0) hour = 23;
            }
        }
    }

    void print() const {
        cout << setfill('0') 
             << setw(2) << hour << ":" 
             << setw(2) << minute << ":" 
             << setw(2) << second << endl;
    }
};

int main() {
    int type;
    while (cin >> type && type != 0) {
        int h, m, s, cnt;
        char op;
        cin >> h >> m >> s >> op >> cnt;

        if (type == 121 || type == 122) {
            Time_12hours t(type, h, m, s);
            for (int i = 0; i < cnt; ++i) {
                if (op == '+') ++t;
                else --t;
            }
            t.print();
        } else if (type == 24) {
            Time_24hours t(h, m, s);
            for (int i = 0; i < cnt; ++i) {
                if (op == '+') ++t;
                else --t;
            }
            t.print();
        }
    }
    return 0;
}

R7-6.2 日程安排(多重继承+重载)

已有一个日期类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

AC:

#include 
#include 
#include 
using namespace std;

// 日期类
class Date {
protected:
    int year;
    int month;
    int day;
public:
    Date(int y, int m, int d) : year(y), month(m), day(d) {}
};

// 时间类
class Time {
protected:
    int hour;
    int minute;
    int second;
public:
    Time(int h, int m, int s) : hour(h), minute(m), second(s) {}
};

// 日程类
class Schedule : public Date, public Time {
private:
    int ID;
public:
    Schedule(int id, int y, int m, int d, int h, int min, int s) : Date(y, m, d), Time(h, min, s), ID(id) {}

    bool operator < (const Schedule & s2) const {
        if (year != s2.year) return year < s2.year;
        if (month != s2.month) return month < s2.month;
        if (day != s2.day) return day < s2.day;
        if (hour != s2.hour) return hour < s2.hour;
        if (minute != s2.minute) return minute < s2.minute;
        return second < s2.second;
    }

    int getID() const {
        return ID;
    }

    void print() const {
        cout << "The urgent schedule is No." << ID << ": " << year << "/" << month << "/" << day << " " << hour << ":" << minute << ":" << second << endl;
    }
};

int main() {
    vector schedules;
    int id, year, month, day, hour, minute, second;
    char c1, c2, c3, c4;

    while (cin >> id && id != 0) {
        cin >> year >> c1 >> month >> c2 >> day >> hour >> c3 >> minute >> c4 >> second;
        schedules.emplace_back(id, year, month, day, hour, minute, second);
    }

    if (!schedules.empty()) {
        auto earliest = *min_element(schedules.begin(), schedules.end());
        earliest.print();
    }

    return 0;
}    

你可能感兴趣的:(c++,算法,开发语言)