问题背景1
在学习面向对象的程序设计(C++语言描述)过程中,为了加深对构造函数、析构函数,子对象理解,在VS2022平台上实现类的各项操作。 有以下题目: 定义一个车轮类Wheel,有两个成员变量分别为车轮半径W_Radius,和车轮宽度W_Width,同时定义一个默认构造函数和一个有两个参数的构造函数来输入车轮的半径和宽度来构造车轮,还要包含一个析构函数,同时添加适当的输入和输出函数。定义一个车辆类Vehicle,要求与上次作业做的车辆类相似,成员数据包括上次作业定义的生产厂家,型号,价格,不同是要求将车轮类的一个对象作为车辆类的子对象。要求在车辆类的构造函数中初始化车轮子对象。在每个构造函数和析构函数中写一个类似于“***函数被调用”的输出方便查看。在main函数中构造车辆类对象,输出车辆的厂家,型号,价格以及车轮信息。并观察说明每个构造函数和析构函数的调用。 ## 操作步骤
- 1.导入标准库头文件与String库。
- 2.创建一个Wheel类与Vehicle类。
- 3.在类中写好变量的定义,以及成员函数的声明与实现。
- 4.写构造函数,并且在其中加入提示语句
- 5.写析构函数,并且在其中加入提示语句
- 6.在Vehicle类中定义Wheel子对象wheel
- 7.使用wheel子对象输出
- 8.定义Vehicle对象a,调用函数显示结果并且分析
代码实现1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <iostream> #include <stdlib.h> #include <string> using namespace std;
class Wheel //车轮类 { protected: double W_Radius; double W_Width; public: Wheel() { W_Radius = 0.0;W_Width = 0.0;cout << "Wheel的默认构造函数被调用" << endl; } Wheel(double r, double w); double Getr() { return W_Radius; } double Getw() { return W_Width; } void setinfo() { cout << "请输入轮子半径以及宽度:" << endl;cin >> W_Radius >> W_Width; }; void show(); ~Wheel() { cout << W_Radius << endl; cout << "Wheel的析构函数被调用" << endl; }; }; Wheel::Wheel(double r, double w) { cout << "Wheel的重载构造函数被调用" << endl; W_Radius = r; W_Width = w; } void Wheel::show() { cout << "半径:" << W_Radius << endl; cout << "宽度:" << W_Width << endl; }
class Vehicle { private: string factory; string model; double price = 0.0; Wheel wheel; public: Vehicle() { cout << "Vehicle的默认构造函数被调用" << endl; }; Vehicle(string factory1, string model1, double price1, double r, double w); void getinfo() { cout << "Vehicle的重载构造函数被调用" << endl; cout << "请输入厂商、型号、价格:" << endl; cin >> factory >> model >> price; wheel.setinfo(); }; void show(); ~Vehicle() { cout << model << endl;cout << "Vehicle的析构函数被调用" << endl; }; }; Vehicle::Vehicle(string factory1, string model1, double price1, double r, double w) :wheel(r, w) { cout << "Vehicle的重载构造函数被调用" << endl; factory = factory1; model = model1; price = price1; }; void Vehicle::show() { cout << "车轮规格:" << endl; wheel.show(); cout << "厂商:" << factory << endl; cout << "型号:" << model << endl; cout << "价格:" << price << endl; }
int main() { Vehicle a; a.getinfo(); a.show(); return 0; }
|
问题背景2
在学习面向对象的程序设计(C++语言描述)过程中,为了加深对静态成员的理解,在VS2022平台上实现类的各项操作。 有以下题目: 定义一个水果类,用以描述某水果店某一天购进水果的总重量及总花费。
要求:
类中有两个私有成员,用以描述水果的单价(元/斤)和购入的重量(斤)。
用静态数据成员统计购进的各种水果加在一起的总重量。
用构造函数来初始化某一种水果的对象,参数为单价及重量。
输入两种水果某日购入的单价和重量,算出并输出当日各个水果的单价,重量,以及总花费及全部水果的总重量之和。
算例:
某日采购苹果30.7斤,单价4.5元/斤
采购香蕉25.8斤,单价3.2元/斤
操作步骤
- 1.导入标准库头文件与String库。
- 2.创建一个Fruit类
- 3.在类中写好变量的定义,以及成员函数的声明与实现。
- 4.创建静态成员数据 totalWeight和totalPrice
- 5.写出求总重量和总价格的函数
- 6.在主函数中用for循环控制水果输入
- 7.输出显示
代码实现2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream>
using namespace std; static double totalWeight=0.0; static double totalPrice=0.0; class Fruit { public: Fruit(double p,double w); void getinfo() { cout << "请输入水果的重量,单价:" << endl;cin >> weight >> price; }; void add(); void times(); double GettotalWeight(); double GettotalPrice(); private: double weight; double price;
};
Fruit::Fruit(double p,double w) { this->weight = w; this->price = p; } double Fruit::GettotalWeight() { return totalWeight; } void Fruit::add() { totalWeight = totalWeight+weight; } void Fruit::times() { double Price = weight * price;totalPrice = totalPrice + Price; } double Fruit::GettotalPrice() { return totalPrice; } int main() { int count; Fruit f(0.0, 0.0); cout << "今天有几种水果?" << endl; cin >> count; for (int i = 0;i < count;i++) { f.getinfo(); f.add(); f.times(); } cout << "此时水果的重量:" << f.GettotalWeight() << endl; cout << "今日水果的价格:" << f.GettotalPrice() << endl;
return 0; }
|
总结
- 对静态成员数据的定义和初始化必须在类的外面,也就是全局作用于中定义。
- 定义时一定要在全局作用域中定义,静态数据成员甚至在类没有任何对象的时候都可以访问,静态成员可以独立访问,不需要依赖任何对象的建立。
- 不建议在头文件中定义静态数据成员,这样做可能会引起定义重复的问题,即使加上了#ifndef等之类的也不行。
- 静态数据成员被类的所有对象共享,包括该类的派生类对象。
- 静态数据成员可以作为成员函数的默认形参,普通数据成员不行。
- 静态数据成员可以在const函数中修改,普通数据不行。
- 静态数据成员可以是所属类的类型,普通数据成员不行。
问题背景3
在学习面向对象的程序设计(C++语言描述)过程中,为了加深对派生类的理解,在VS2022平台上实现类的各项操作。 有以下题目: 在本次作业第1题的基础上,由车辆类派生出摩托车Motorcycle子类以及小汽车Car子类,保留Vehicle类中的Wheel子对象。在Motorcycle类中添加一个车把Handlebar成员变量描述车把长度,在Car类中添加一个方向盘SteeringWheel成员变量描述方向盘半径,各个类中都添加构造函数和析构函数,并在函数中给出适当输出以方便识别函数的调用。在两个子类的构造函数中直接初始化父类及自己的成员变量。在main函数中构造Motorcycle类和Car类对象,并显示相关信息。观察并说明每个构造函数和析构函数的调用。
操作步骤
- 1.导入标准库头文件与String库。
- 2.创建一个Fruit类
- 3.在类中写好变量的定义,以及成员函数的声明与实现。
- 4.创建静态成员数据 totalWeight和totalPrice
- 5.写出求总重量和总价格的函数
- 6.在主函数中用for循环控制水果输入
- 7.输出显示
代码实现3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <iostream> #include <stdlib.h> #include <string> using namespace std;
class Wheel //车轮类 { protected: double W_Radius; double W_Width; public: Wheel() { W_Radius = 0.0;W_Width = 0.0;cout << "Wheel的默认构造函数被调用" << endl; } Wheel(double r, double w); double Getr() { return W_Radius; } double Getw() { return W_Width; } void setinfo() { cout << "请输入轮子半径以及宽度:" << endl;cin >> W_Radius >> W_Width; }; void show(); ~Wheel() { cout << W_Radius << endl;cout << "Wheel的析构函数被调用" << endl; }; }; Wheel::Wheel(double r, double w) { cout << "Wheel的重载构造函数被调用" << endl; W_Radius = r; W_Width = w; } void Wheel::show() { cout << "半径:" << W_Radius << endl; cout << "宽度:" << W_Width << endl; }
class Vehicle { private: string factory; string model; double price = 0.0; Wheel wheel; public: Vehicle() { cout << "Vehicle的默认构造函数被调用" << endl; }; Vehicle(string factory1, string model1, double price1, double r, double w); void getinfo() { cout << "Vehicle的重载构造函数被调用" << endl; cout << "请输入厂商、型号、价格:" << endl; cin >> factory >> model >> price; wheel.setinfo(); }; void show(); ~Vehicle() { cout << model << endl;cout << "Vehicle的析构函数被调用" << endl; }; }; Vehicle::Vehicle(string factory1, string model1, double price1, double r, double w) :wheel(r, w) { cout << "Vehicle的重载构造函数被调用" << endl; factory = factory1; model = model1; price = price1; }; void Vehicle::show() { cout << "车轮规格:" << endl; wheel.show(); cout << "厂商:" << factory << endl; cout << "型号:" << model << endl; cout << "价格:" << price << endl; }
class Motorcycle: public Vehicle{ public: double Handlebar; Motorcycle() { Handlebar = 10.0;cout << "Motorcycle默认构造函数被调用" << endl; }; ~Motorcycle() { cout << Handlebar << endl;cout << "Motorcycle析构函数被调用" << endl; }; void showhandlebar() { cout << "车把长度为:" << Handlebar << endl; }; }; class Car: public Vehicle{ public: double SteeringWheel=0.0; Car() { SteeringWheel = 15.0;cout << "Car类默认构造函数被调用" << endl; }; ~Car() { cout << SteeringWheel << endl;cout << "Car类析构函数被调用" << endl; }; void showSteeringWheel() { cout << "方向盘半径是:" << SteeringWheel << endl; }; };
int main() { Vehicle a; a.getinfo(); a.show(); Motorcycle m; Car c; m.showhandlebar(); c.showSteeringWheel(); return 0; }
|
总结
- 派生类==子类。
- 定义形式claas 派生类名:派生类派生方式 基类名{}
- 含有派生类的代码构造函数调用顺序是先调用基类,再调用子对象的构造函数初始化,最后调用派生类,析构函数则相反,先析构派生类,再析构子对象,最后析构基类。
- 在派生类中,如果对派生类新增的成员进行初始化,就需要加入派生类的构造函数。与此同时,对所有从基类继承下来的成员的初始化工作,还是由基类的构造函数完成,但是基类的构造函数和析构函数不能被继承,因此必须在派生类的构造函数中对基类的构造函数所需要的参数进行设置。同样,对撤销派生类对象的扫尾、清理工作也需要加入新的析构函数来完成。
- 含有子对象的类的构造调用: ①子对象调构造函数(子对象自己的) ②再执行自己的函数体 ③含有子对象的析构函数的调用,严格与构造函数相反