实验二: 继承与派生实验
实验题目(1): 定义一个车基类,派生出自行车类和汽车类,又以自行车类和汽车类为基类共同派生出摩托车类,每个类都要定义带有参数的构造函数。对自行车类继承车基类的方式分别用private、protected、public,观察基类成员在派生类中的访问属性;观察自行车类、汽车类和摩托车类对象定义时构造、析构函数的调用顺序。最后将车基类定义为虚基类再观察程序运行结果。
实验解答:
- 根据提示进行填写完整实验指导204页代码对应位置内容如下:
( 1 ) MaxSpeed=m;
( 2 ) Weight=w;
( 3 ) Vehicle(m,w)
( 4 ) Height=h;
( 5 ) Vehicle::show();
( 6 ) cout<<”It’s height is :”<<Height<<endl;
( 7 ) (100,10000,900)
此时程序的运行结果是:
Constructing Vehicle...
Constructing Bicycle...
The vehicle is running!
Please stop running!
It's maxspeed is:100
It's weight is :10000
It's height is :900
Destructing Bicycle...
Destructing Vehicle...
- 将继承方式改为private或protected,观察并分析程序的编译结果。
“Vehicle::Run”不可访问,因为“Bicycle”使用“private”从“Vehicle”继承
“Vehicle::Stop”不可访问,因为“Bicycle”使用“private”从“Vehicle”继承
- 在Bicycle类下面增加Car类的定义,参考实验教材205代码,划线部分自己完成。
( 8 ) Vehicle(m,w)
( 9 ) SeatNum=s;
( 10 ) Vehicle::Show();
( 11 ) cout<<"The number of seats is :"<<SeatNum<<endl;
( 12 ) b (100,10000,900);
( 13 ) c(300,100,200);
- 增加的第3层类MotorCycle及修改以后的main( )函数,代码参见实验教材206页。
( 14 ) Bicycle(h),Car(s)
( 15 ) mc(280,3000,120,2) ;
⑤ 将Vehicle声明为虚基类以消除二义性,具体要在上面的基础上修改3个地方。
· 将class Bicycle: public Vehicle 修改为 class Bicycle: virtual public Vehicle。
· 将class Car: public Vehicle 修改为 class Car: virtual public Vehicle。
· 在第3层类的构造函数MotorCycle(int m,int w,int h,int s): (16) 的初始化列表中增加对虚基类构造函数的调用。
( 16 ) Bicycle(h),Car(s) ,Vehicle(h,m)
实验题目(2):定义Base类及它的公有派生类Derived类,两个类中均定义带参数的构造函数,基类中定义函数Show( ),派生类中也定义一个同名的Show( ),二者输出内容有所区别。主函数中定义基类的对象、指针、引用,也定义派生类的对象。
① 对赋值兼容的4种情况作测试,对每行的输出结果进行观察,理解赋值兼容何时调用基类的成员函数,什么情况下才会调用派生类的成员函数。
② 在主函数的return 0;语句前增加4条语句,观察并记下编译时的报错信息,理解赋值兼容的不可逆性。
实验解答:
- 按提示将程序填写完整,代码参见实验教材206-207页,对应位置内容是:
(1 ) b1(2);
(2 ) d1(4);
(3 ) b1=d1;
(4 ) &b2=d1;
(5 ) *b3=&d1;
(6 ) new Derived(5);
程序的运行结果是:
基类对象 b1.show():
i in Base is:2
基类b1=d1, b1.show():
i in Base is:4
派生类对象 d1.show():
i in Derived is:4
引用b2=d1,b2.show():
i in Base is:4
基类指针b3=&d1,b3->show():
i in Base is:4
基类指针b4=d4,b4->show():
i in Base is:5
派生类指针d4 d4->show():
i in Derived is:5
- 在主函数的return 0;语句前增加4条语句:
Derived d5=b1;
Derived &d6=b1;
Derived *d7=&b1;
d7=b3;
观察并记下编译时的报错信息,理解赋值兼容的不可逆性。
“初始化”: 无法从“Base”转换为“Derived”
无构造函数可以接受源类型,或构造函数重载决策不明确
“初始化”: 无法从“Base”转换为“Derived &”
“初始化”: 无法从“Base *”转换为“Derived *”
从基类型到派生类型的强制转换需要 dynamic_cast 或 static_cast
“=”: 无法从“Base *”转换为“Derived *”
从基类型到派生类型的强制转换需要 dynamic_cast 或 static_cast