实验4 继承

实验任务2

<task2.cpp>

 1 #include<iostream>
 2 #include<typeinfo>
 3 
 4 class Graph
 5 {
 6     public:
 7     void draw(){std::cout << "Graph::draw() : just as an interface\n";}
 8 };
 9 
10 class Rectangle : public Graph
11 {
12     public:
13     void draw(){std::cout <<"Rectangle::draw() : programs of draw a rectangle\n";}
14 };
15 
16 class Circle : public Graph
17 {
18     public:
19     void draw(){std::cout <<"Circle::draw() : programs of draw a circle\n";}
20 };
21 
22 void fun(Graph *ptr)
23 {
24     std::cout << "pointer type: " << typeid(ptr).name() << "\n";
25     std::cout << "RTTI type: " << typeid(*ptr).name() << "\n";
26     ptr->draw();
27 }
28 int main()
29 {
30     Graph g1;
31     Rectangle r1;
32     Circle c1;
33 
34     g1.draw();
35     r1.draw();
36     c1.draw();
37 
38     std::cout << "\n";
39 
40     r1.Graph::draw();
41     c1.Graph::draw();
42 
43     std::cout << "\n";
44 
45     fun(&g1);
46     fun(&r1);
47     fun(&c1);
48 }

运行结果:

同名覆盖原则:派生类和基类具有相同成员时,通过派生类对象访问,默认访问的是派生类的同名成员

二元作用域分辨符(::):用于显式指定使用的是哪个类的重名成员

类型兼容原则:派生类对象也可以当作基类对象来使用,但只能使用从基类继承的那部分功能

在Graph类的成员函数draw()前加上virtual,重新编译运行。结果为:

调用虚函数时,根据指针实际指向的对象,选择相应的函数实现。

实验任务3

使用类的组合和继承模拟简单的车辆信息管理。

<battery.hpp>

 1 #ifndef BATTERY_HPP
 2 #define BATTERY_HPP
 3 
 4 class Battery
 5 {
 6 public:
 7     Battery(int cap=70):capacity{cap}{}
 8     //Battery(Battery& b):capacity(b.capacity){}
 9     int get_capacity(){return capacity;}
10 private:
11     int capacity;
12 };
13 #endif

<car.hpp>

 1 #ifndef CAR_HPP
 2 #define CAR_HPP
 3 
 4 #include <iostream>
 5 #include <iomanip>
 6 using namespace std;
 7 class Car
 8 {
 9 public:
10     Car() = default;
11     Car(string ma, string mo, int y, int meters = 0);
12     void info();
13     void update_odometers(int meters);
14 
15     string maker;  //制造商
16     string model;  //型号
17     int year;      //生产年份
18     int odometers; //行车里程数
19 };
20 
21 Car::Car(string ma, string mo, int y, int meters)
22 {
23     maker = ma;
24     model = mo;
25     year = y;
26     odometers = meters;
27 }
28 
29 void Car::info()
30 {
31     cout.setf(ios::left);
32     cout << setw(20) << "maker:" << maker << endl;
33     cout << setw(20) << "model:" << model << endl;
34     cout << setw(20) << "year:" << year << endl;
35     cout << setw(20) << "odometers:" << odometers << endl;
36 }
37 
38 void Car::update_odometers(int meters)
39 {
40     if (meters < odometers)
41         cout << "new odometers is wrong!!!" << endl;
42     else
43     {
44         odometers = meters;
45     }
46 }
47 #endif

<electricCar.hpp>

 1 #ifndef ELECTRICCAR_HPP
 2 #define ELECTRICCAR_HPP
 3 
 4 #include"battery.hpp"
 5 #include"car.hpp"
 6 using namespace std;
 7 
 8 class ElectricCar : public Car
 9 {
10 public:
11     ElectricCar(string ma,string mo,int y,int cap=70,int meters=0):Car(ma,mo,y,meters),battery(cap){}
12     void info();
13 private:
14     Battery battery;
15 };
16 
17 void ElectricCar::info()
18 {
19     cout.setf(ios::left);
20     cout << setw(20) << "maker:" << maker << endl;
21     cout << setw(20) << "model:" << model << endl;
22     cout << setw(20) << "year:" << year << endl;
23     cout << setw(20) << "odometers:" << odometers << endl;
24     cout << setw(20) << "capacity:" << battery.get_capacity() <<"-kWh"<< endl;
25 }
26 #endif

<task3.cpp>

 1 #include <iostream>
 2 #include "electricCar.hpp"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7 
 8     // test class of Car
 9     Car oldcar("BWM", "a4", 2016);
10     cout << "--------oldcar's info--------" << endl;
11     oldcar.update_odometers(25000);
12     oldcar.info();
13 
14     cout << endl;
15 
16     // test class of ElectricCar
17     ElectricCar newcar("Tesla", "model A", 2016);
18     newcar.update_odometers(5000);
19     cout << "\n--------newcar's info--------\n";
20     newcar.info();
21 }

测试结果:

 实验任务4

使用类的继承,模拟简单的机器宠物。

<pets.hpp>

 1 #ifndef PETS_HPP
 2 #define PETS_HPP
 3 
 4 using namespace std;
 5 class MachinePets
 6 {
 7 public:
 8     MachinePets(const string s) : nickname{s} {}
 9     string get_nickname() const { return nickname; }
10     virtual string talk() { return "ze~ze~"; }
11 
12 private:
13     string nickname;
14 };
15 
16 class PetCats : public MachinePets
17 {
18 public:
19     PetCats(const string s) : MachinePets(s) {}
20     string talk()
21     {
22         return "miao wu~";
23     }
24 };
25 
26 class PetDogs : public MachinePets
27 {
28 public:
29     PetDogs(const string s) : MachinePets(s) {}
30     string talk()
31     {
32         return "wang wang~";
33     }
34 };
35 #endif

<task4.cpp>

 1 #include <iostream>
 2 #include "pets.hpp"
 3 
 4 void play(MachinePets *ptr)
 5 {
 6     std::cout << ptr->get_nickname() << " says " << ptr->talk() << std::endl;
 7 }
 8 
 9 int main()
10 {
11     PetCats cat("miku");
12     PetDogs dog("da huang");
13 
14     play(&cat);
15     play(&dog);
16 }

测试结果:

总结与体会

1、加了{}就是定义了,而不是声明

2、派生类构造函数初始化,通过参数化列表,先调用基类构造函数初始化基类,再初始化派生类成员

3、有默认值的形参才可以没有实参

posted @ 2021-11-29 00:02  dd摇摆  阅读(13)  评论(2)    收藏  举报