实验目的
1. 理解类的继承和派生机制
2. 掌握派生类的定义和使用
3. 理解和掌握派生类成员的标识和访问中同名覆盖原则、二元作用域分辨符和虚基类的用法
4. 掌握派生类构造函数和析构函数的定义及调用次序
5. 理解运算符重载的目的,掌握运算符重载函数的编写方法
实验内容
1. 车辆基本信息管理 问题场景描述如下: 为了对车量基本信息进行管理,对现实世界车量基本信息抽象后,抽象出Car类、ElectricCar类、Battery类, 它们之间的关系描述如下:基于Car类派生出ElectricCar类,派生类ElectricCar中新增数据成员为Battery类 对象。
基于以下描述设计并实现Battery类
- 每个Battery类对象有如下信息:
车载动力电池容量(batterySize)
- 要求Battery类提供成员函数实现以下要求:
带有默认形参值的构造函数。
实现Battery类对象的构造,在构造对象时对电池容量batterySize 进行初始化,默认参数值为70(单位: kWh)。
返回当前电池容量。
基于以下描述设计并实现Car类
- 每辆汽车有如下信息:
制造商(maker), 型号(model), 生产年份(year), 行车里程数(odometer)。
- 要求Car类提供成员函数实现以下要求:
带参数的构造函数。实现Car类对象的构造,并在构造对象时实现对制造商、型号、生产年份的 初始化。初始构造时,行车里程数总是0。
重载运算符<<为Car类友元。实现车辆信息显示输出,输出信息包括:制造商、型号、生产年 份、当前行车里程数。
更新行车里程数。更新后的行车里程数通过参数传递。要求能对参数进行合理性检查,如果更 新后的行车里程数值小于当前行车里程数,打印警告信息,提示更新数值有误。
基于以下描述设计并实现ElectricCar类
- ElectricCar类继承自Car类,新增数据成员电池(battery)。其中,battery是Battery类对象。
- 带参数的构造函数。
- 实现ElectricCar类对象的构造,并在构造时实现对制造商、型号、生产年份以及 新增数据成员电池的初始化。初始构造时,行车里程数总是0。
- 重载运算符<<为ElectricCar类友元。实现车辆信息显示输出,包括:制造商、型号、生产年份、当前 行车里程数、当前电池容量。
1 #ifndef CAR_H 2 #define CAR_H 3 4 #include <iostream> 5 #include <string> 6 7 using namespace std; 8 9 class Car { 10 public: 11 Car(string maker0,string model0,int year0,long odometer0=0); 12 friend std::ostream & operator<< (std::ostream &out,const Car &c); 13 void updateOdometer (long odometer0); 14 private: 15 string maker; 16 string model; 17 int year; 18 long odometer; 19 }; 20 21 #endif
1 #ifndef BATTERY_H 2 #define BATTERY_H 3 4 class Battery { 5 public: 6 Battery (); 7 int back() const; 8 private: 9 int number; 10 }; 11 12 #endif
1 #ifndef ELECTRIC_H 2 #define ELECTRIC_H 3 4 #include <iostream> 5 #include <string> 6 #include "battery.h" 7 #include "car.h" 8 9 using namespace std; 10 11 class ElectricCar:public Car{ 12 public: 13 ElectricCar(string maker0, string model0, int year0,long odometer0=0); 14 friend std::ostream & operator<< (std::ostream &out, const ElectricCar &c); 15 private: 16 Battery battery; 17 }; 18 19 #endif
1 #include <iostream> 2 #include <string> 3 #include "car.h" 4 5 using namespace std; 6 7 Car::Car (string maker0, string model0, int year0, long odometer0):maker(maker0),model(model0),year(year0),odometer(odometer0){ 8 } 9 10 ostream & operator<< (std::ostream &out,const Car &c) { 11 out << c.maker << endl; 12 out << c.model << endl; 13 out << c.year << endl; 14 out << c.odometer; 15 return out; 16 } 17 18 void Car::updateOdometer (long odometer0) { 19 if (odometer0 <odometer) cout << "Error!" << endl; 20 else odometer = odometer0; 21 }
1 #include <iostream> 2 #include "battery.h" 3 4 using namespace std; 5 6 Battery::Battery():number(70) { 7 } 8 9 int Battery::back() const{ 10 return number; 11 }
1 #include "electricCar.h" 2 #include "car.h" 3 #include <iostream> 4 #include <string> 5 6 using namespace std; 7 8 ElectricCar::ElectricCar(string maker0, string model0, int year0, long odometer0):Car(maker0, model0, year0,odometer0) { 9 } 10 11 ostream & operator<< (std::ostream &out, const ElectricCar &c) { 12 Car a(c); 13 out << a; 14 out << c.battery.back() << "kWh" << endl; 15 return out; 16 }
1 #include <iostream> 2 3 using namespace std; 4 5 #include "car.h" 6 #include "electricCar.h" 7 8 int main() { 9 // 测试Car类 10 Car oldcar("Audi","a4",2016); 11 cout << "--------oldcar's info--------" << endl; 12 oldcar.updateOdometer(25000); 13 cout << oldcar << endl; 14 15 // 测试ElectricCar类 16 ElectricCar newcar("Tesla","model s",2016); 17 newcar.updateOdometer(2500); 18 cout << "\n--------newcar's info--------\n"; 19 cout << newcar << endl; 20 21 system("pause"); 22 23 return 0; 24 }
2.补足程序,重载运算符[]为一维动态整形数组类ArrayInt的成员函数,使得通过动态整形数组对象名和下标可以 访问对象中具体元素。
1 #ifndef ARRAY_INT_H 2 #define ARRAY_INT_H 3 using namespace std; 4 5 class ArrayInt{ 6 public: 7 ArrayInt(int n, int value=0); 8 ~ArrayInt(); 9 int &operator[] (int a); 10 void print(); 11 private: 12 int *p; 13 int size; 14 }; 15 16 #endif
1 #include "arrayInt.h" 2 #include <iostream> 3 #include <cstdlib> 4 using std::cout; 5 using std::endl; 6 7 ArrayInt::ArrayInt(int n, int value): size(n) { 8 p = new int[size]; 9 10 if (p == nullptr) { 11 cout << "fail to mallocate memory" << endl; 12 exit(0); 13 } 14 15 for(int i=0; i<size; i++) 16 p[i] = value; 17 } 18 19 ArrayInt::~ArrayInt() { 20 delete[] p; 21 } 22 23 void ArrayInt::print() { 24 for(int i=0; i<size; i++) 25 cout << p[i] << " "; 26 cout << endl; 27 } 28 29 int & ArrayInt::operator[] (int a) { 30 return p[a]; 31 }
1 #include <iostream> 2 using namespace std; 3 4 #include "arrayInt.h" 5 6 int main() { 7 // 定义动态整型数组对象a,包含2个元素,初始值为0 8 ArrayInt a(2); 9 a.print(); 10 11 // 定义动态整型数组对象b,包含3个元素,初始值为6 12 ArrayInt b(3, 6); 13 b.print(); 14 15 // 通过对象名和下标方式访问并修改对象元素 16 b[0] = 2; 17 cout << b[0] << endl; 18 b.print(); 19 20 system("pause"); 21 22 return 0; 23 }
实验总结与体会
1.课上做有了压力之后做出来的程序问题太多,课后做的也是问题比较多,做起来不是很流畅然后也就不是很舒服。
2.感觉上课上的内容用到的只有很少一部分,在自己做的环境下问题也就逐渐增多。
3.说到底还是写的不够多,平时也没有练习的意思,或许可以多看看书吧,至少理论上要稍微熟悉。