第3题:在第4题的基础上,由客车类和货车类再派生出一个客货两用车类,一辆客货两用车既具有客车的特征(有座位,可以载客),又具有货车的特征(有装载车厢,可以载货)。要求将客货两用车类的间接共同基类——汽车类声明为虚基类。要求:基类和派生类的成员函数根据自己需要提供。
1.编写程序
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
class Car { //定义基类Car
public:
Car(); //不带参数的构造函数
Car(string mo, string co, string po, string sp, string qu, string nu) :model(mo), color(co), power(po), speed(sp), quality(qu), number(nu) {}; //带参数的构造函数
void show(); //基类的show函数
private:
string model; //型号
string color; //颜色
string power; //发动机功率
string speed;//车速
string quality;//质量 差/良
string number;//车牌号
};
class Bus: virtual public Car { //定义派生类Bus,共有继承Car
public:
Bus(); //不带参数的构造函数
Bus(string mo, string co, string po, string sp, string qu, string nu, string si, string com) :Car(mo, co, po, sp, qu, nu), sitnum(si), company(com) {}; //带参数的构造函数
void show(); //和基类同名的show函数,派生类同名函数会屏蔽基类同名函数
void show1() {
cout << "座位数:" << sitnum << endl; //输出新增成员信息
}
private:
string sitnum; //座位数
string company;//客运公司
};
class Truck: virtual public Car { //定义派生类Truck,共有继承Car
public:
Truck(); //不带参数的构造函数
Truck(string mo, string co, string po, string sp, string qu, string nu, string lo, string com) :Car(mo, co, po, sp, qu, nu), load(lo), company(com) {}; //带参数的构造函数
void show();//和基类同名的show函数,派生类同名函数会屏蔽基类同名函数
void show1() {
cout << "载货重量:" << load << endl; //输出新增成员信息
cout << "客运公司:" << company << endl;
}
private:
string load; //载货重量
string company; //货运公司
};
class BTcar: public Bus, public Truck {
public:
BTcar() {};
BTcar(string mo, string co, string po, string sp, string qu, string nu, string si, string com, string lo) :Car(mo, co, po, sp, qu, nu), Bus(mo, co, po, sp, qu, nu, si, com), Truck(mo, co, po, sp, qu, nu, lo, com) {};
void show();
};
Car::Car() { //不带参数的构造函数
cout << "请输入型号、颜色、发动机功率(W)、车速、质量(良/差)和车牌号:(以空格隔开)" << endl;
cin >> model >> color >> power>>speed>>quality>>number; //用户手动输入数据,创建对象
}
void Car::show()
{
cout << "型号:" << model << endl;
cout << "颜色:" << color<< endl;
cout << "发动机功率:" << power <<"W" << endl;
cout << "车速:" << speed << "km/h"<<endl;
cout << "质量:" << quality << endl;
cout << "车牌号:" << number<< endl;
}
Bus::Bus() //派生类的不带参数的构造函数,因为基类存在不带参数的构造函数,所以在该函数中,系统会自动调用基类的无参构造函数
{
cout << "请输入客车座位数和客运公司名称(以空格隔开):" << endl;
cin >> sitnum>>company; //用户输入数据,初始化新增成员
}
void Bus::show() //和基类同名的show函数,派生类同名函数会屏蔽基类同名函数
{
cout << "客车信息如下:" << endl;
Car::show(); //调用基类被隐藏的同名函数,需要运用作用域限定符“:”
cout << "座位数:" <<sitnum<<endl; //输出新增成员信息
cout << "客运公司:" << company << endl;
}
Truck::Truck() //派生类的不带参数的构造函数,因为基类存在不带参数的构造函数,所以在该函数中,系统会自动调用基类的无参构造函数
{
cout << "请输入载货重量(t)和货运公司:(以空格隔开)" << endl;
cin >> load >> company; //用户输入数据,初始化新增成员
}
void Truck::show() //和基类同名的show函数,派生类同名函数会屏蔽基类同名函数
{
cout << "货车信息如下:" << endl;
Car::show(); //调用基类被隐藏的同名函数,需要运用作用域限定符“:”
cout << "载货重量:"<<load << endl; //输出新增成员信息
cout << "货运公司:" << company<< endl;
}
void BTcar::show()
{
cout << "客货两用车信息如下:" << endl;
Car::show();
Bus::show1();
Truck::show1();
}
int main()
{
cout << " --创建客货两用车BTcar1信息--" << endl;
BTcar BTcar1; //创建客货两用车BTcar1信息,在构造函数中用户手动输入数据
BTcar1.show();
cout << " --创建客货两用车BTcar2信息--" << endl;
BTcar BTcar2("大型", "红色", "4500", "90", "良", "C12345", "30", "客运公司", "20"); // 调用带参数的构造函数,使用参数来初始化BTcar2的属性和新增成员变量
BTcar2.show(); // 展示BTcar2的属性和新增成员变量
return 0;
}
2.运行结果
3.程序分析
程序定义了四个类,基类Car及其派生类Bus类和Truck类,还有基于派生类Bus类和Truck类派生出的BTcar类。
- Car类:
Car类在直接派生类中被声明为虚基类,对直接派生类不会产生影响,对其后面的派生类,在多重继承具有共同基类的直接基类时,只保留一份成员,避免了二义性。
公有区域:一个不带参数的构造函数Car,在函数体内,先提示用户输入,然后用户输入数据来初始化数据。另一个带参数的构造函数则需要主函数传入形参来初始化数据,另外也可以使用初始化列表对数据进行初始化。函数show用来展示基类数据成员,有六条输出语句。
私有区域:定义六个string数据成员,分别为model(型号)、color(颜色)、power(发动机功率)、speed(车速)、quality(质量)和number(车牌号)。
- Bus类(共有继承基类并将Car声明为虚基类):
公有区域:一个不带参数的构造函数Bus,派生类的不带参数的构造函数,因为基类存在不带参数的构造函数,所以在该函数中,系统会自动调用基类的无参构造函数,在函数体内,先提示用户输入,然后用户输入新增成员的数据来初始化数据。另一个带参数的构造函数Bus则需要主函数传入形参来初始化数据,另外也可以使用初始化列表对数据进行初始化。函数show用来展示派生类新增数据成员,和基类同名的show函数,派生类同名函数会屏蔽基类同名函数,因此调用基类被隐藏的同名函数,需要运用作用域限定符“:”,有三条输出语句。 函数show1用来展示Bus私有的数据成员sitnum(座位数),有1条输出语句。
私有区域:仅定义了两个string数据成员,sitnum(座位数)和company(客运公司)。
- Truck类(共有继承基类并将Car声明为虚基类):
公有区域: 一个不带参数的构造函数Truck,派生类的不带参数的构造函数,因为基类存在不带参数的构造函数,所以在该函数中,系统会自动调用基类的无参构造函数,在函数体内,先提示用户输入,然后用户输入新增成员的数据来初始化数据。另一个带参数的构造函数Truck则需要主函数传入形参来初始化数据,另外也可以使用初始化列表对数据进行初始化。函数show用来展示派生类数据成员的函数,和基类同名的show函数,派生类同名函数会屏蔽基类同名函数,因此调用基类被隐藏的同名函数,需要运用作用域限定符“:”,有三条输出语句。Show1函数用来展示Truck私有数据成员load,有一条输出语句。
私有区域:定义了两个string数据成员,load(载货重量)和company(货运公司)。
- BTcar类(共有继承Bus和Truck类)
公有区域:一个不带参数的构造函数BTcar,派生类的不带参数的构造函数,因为基类存在不带参数的构造函数,所以在该函数中,系统会自动调用直接基类的无参构造函数。另一个带参数的构造函数BTcar则需要主函数传入形参来初始化数据,使用初始化列表对数据进行初始化时,首先调用虚基类Car的构造函数,其次调用直接基类Bus类的构造函数,最后调用直接基类Truck的构造函数。函数show用来展示派生类数据成员的函数,和基类同名的show函数,派生类同名函数会屏蔽基类同名函数,因此调用基类被隐藏的同名函数,需要运用作用域限定符“:”,先调用虚基类Car的show函数,其次调用直接基类Bus的show1函数,最后调用直接基类Truck的show1函数,有一条输出语句。Show1函数用来展示Truck私有数据成员load,有一条输出语句。
- 主函数:
首先定义一个派生类BTcar对象BTcar1,同时系统会自动调用派生类的无参数构造函数来初始化BTcar1的数据成员,然后输出BTcar1的所有数据信息。
然后再定义一个派生类BTcar2 对象BTcar2,调用派生类的有参数构造函数,将实参传入构造函数来初始化Btcar2的数据成员,然后输出BTcar2的所有数据信息。