实验4 继承
实验任务2
- 基类Graph的成员函数draw()前面不加关键字virtual时
源代码:
1 #include <iostream> 2 #include <typeinfo> 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 4 class Graph 5 { 6 public: 7 void draw() 8 { 9 std::cout<<"Graph::draw() : just as an interface\n"; 10 } 11 }; 12 class Rectangle :public Graph 13 { 14 public : 15 void draw() 16 { 17 std::cout<<"Rectangle::draw() : programes of draw a rectangle\n"; 18 } 19 }; 20 class Circle : public Graph 21 { 22 public : 23 void draw() 24 { 25 std::cout<<"Circle::draw() : programes of draw a circle\n"; 26 } 27 }; 28 void fun(Graph *ptr) 29 { 30 //获取运行时指针变量ptr的类型信息 31 std::cout<<"pointer type: "<<typeid(ptr).name()<<std::endl;//typeid可以用于获取运行时类型信息。 32 //获取运行时指针变量ptr实际指向的对象的类型信息。 33 //RTTI,Runtime Type Info的首字母缩写,运行时类型信息. 34 std::cout<<"RTTI type: "<<typeid(*ptr).name()<<std::endl; 35 ptr->draw(); 36 } 37 38 int main() { 39 Graph g1; 40 Rectangle r1; 41 Circle c1; 42 g1.draw(); 43 r1.draw(); 44 c1.draw(); 45 std::cout<<std::endl; 46 r1.Graph::draw(); 47 c1.Graph::draw(); 48 std::cout<<std::endl; 49 fun(&g1); 50 fun(&r1); 51 fun(&c1); 52 }
运行结果:
总结:
同名覆盖原则:LINE7、15、23分别是3个同名函数的定义,在调用时,如果像LINE42、43、44那样不添加作用域,直接调用的话,调用的是继承类中的同名函数,即继承类中同名函数将基类同名 函数覆盖。
二元作用域分辨符:LINE7、15、23分别是3个同名函数的定义,在调用时,如果像LINE46、47那样添加作用域调用的话,调用的是对应作用域中的同名函数。
类型兼容原则:LINE28中,定义了形参的类型是指向Graph类型的指针,所以不管传入的是rectangle类的对象地址还是circle类的对象地址,都只能访问基类graph中继承来的公有成员。
- 基类Graph的成员函数draw()前面加关键字virtual时
源代码:
1 #include <iostream> 2 #include <typeinfo> 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 4 class Graph 5 { 6 public: 7 virtual void draw() 8 { 9 std::cout<<"Graph::draw() : just as an interface\n"; 10 } 11 }; 12 class Rectangle :public Graph 13 { 14 public : 15 void draw() 16 { 17 std::cout<<"Rectangle::draw() : programes of draw a rectangle\n"; 18 } 19 }; 20 class Circle : public Graph 21 { 22 public : 23 void draw() 24 { 25 std::cout<<"Circle::draw() : programes of draw a circle\n"; 26 } 27 }; 28 void fun(Graph *ptr) 29 { 30 //获取运行时指针变量ptr的类型信息 31 std::cout<<"pointer type: "<<typeid(ptr).name()<<std::endl;//typeid可以用于获取运行时类型信息。 32 //获取运行时指针变量ptr实际指向的对象的类型信息。 33 //RTTI,Runtime Type Info的首字母缩写,运行时类型信息. 34 std::cout<<"RTTI type: "<<typeid(*ptr).name()<<std::endl; 35 ptr->draw(); 36 } 37 38 int main() { 39 Graph g1; 40 Rectangle r1; 41 Circle c1; 42 g1.draw(); 43 r1.draw(); 44 c1.draw(); 45 std::cout<<std::endl; 46 r1.Graph::draw(); 47 c1.Graph::draw(); 48 std::cout<<std::endl; 49 fun(&g1); 50 fun(&r1); 51 fun(&c1); 52 }
运行结果:
- 对比:见红线标出
实验任务三
源代码:
- battery.hpp
1 #ifndef BATTERY_HPP 2 #define BATTERY_HPP 3 #include <iostream> 4 using namespace std; 5 class Battery 6 { 7 private: 8 int capacity; 9 public: 10 Battery(int c); 11 int get_capacity(); 12 ~Battery(){ 13 }; 14 }; 15 Battery::Battery(int c=70):capacity(c){ 16 } 17 int Battery::get_capacity(){ 18 return capacity; 19 } 20 #endif
- car.hpp
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 #include <iostream> 4 #include <iomanip> 5 using namespace std; 6 class Car{ 7 protected: 8 string maker; 9 string model; 10 int year; 11 int odometers; 12 public: 13 Car(string ma,string mo,int y); 14 void info(); 15 void update_odometers(int o); 16 ~Car(){ 17 }; 18 }; 19 Car::Car(string ma,string mo,int y):maker(ma),model(mo),year(y),odometers(0){ 20 } 21 void Car::info(){ 22 cout<<setiosflags(ios::left); 23 cout<<setw(15)<<"maker:"<<maker<<endl; 24 cout<<setw(15)<<"model:"<<model<<endl; 25 cout<<setw(15)<<"year:"<<year<<endl; 26 cout<<setw(15)<<"odometers:"<<odometers<<endl; 27 } 28 void Car::update_odometers(int o){ 29 if(o<odometers) 30 { 31 cout<<"更新数值有误!"<<endl; 32 } 33 else 34 { 35 odometers=o; 36 } 37 } 38 #endif
- electricCar.hpp
1 #ifndef ELECTRICAR_HPP 2 #define ELECTRICAR_HPP 3 #include <iostream> 4 //#include <manip> 5 #include "battery.hpp" 6 #include "car.hpp" 7 class ElectriCar:public Car{ 8 protected: 9 Battery battery; 10 public: 11 ElectriCar(string ma,string mo,int y,int b=70):Car(ma,mo,y),battery(b){ 12 }; 13 void info(); 14 }; 15 void ElectriCar::info() 16 { 17 cout<<setiosflags(ios::left); 18 cout<<setw(15)<<"maker:"<<maker<<endl; 19 cout<<setw(15)<<"model:"<<model<<endl; 20 cout<<setw(15)<<"year:"<<year<<endl; 21 cout<<setw(15)<<"odometers:"<<odometers<<endl; 22 cout<<setw(15)<<"capacity:"<<battery.get_capacity()<<"-kWh"<<endl; 23 } 24 #endif
- task3.cpp
1 #include <iostream> 2 #include "electriCar.hpp" 3 #include"car.hpp" 4 int main() 5 { 6 using namespace std; 7 8 // test class of Car 9 Car oldcar("MAYBACH", "s450", 2016); 10 cout << "--------oldcar's info--------" << endl; 11 oldcar.update_odometers(25000); 12 13 oldcar.info(); 14 15 cout << endl; 16 17 // test class of ElectricCar 18 ElectriCar newcar("Audi", "q2le-tron", 2016); 19 newcar.update_odometers(2500); 20 21 cout << "\n--------newcar's info--------\n"; 22 newcar.info(); 23 }
运行结果:
当更新后的行车里程数值小于当前行车里程数,打印警告信息,提示更新数值有误:
- task3.cpp
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 #include <iostream> 4 #include <iomanip> 5 using namespace std; 6 class Car{ 7 protected: 8 string maker; 9 string model; 10 int year; 11 int odometers; 12 public: 13 Car(string ma,string mo,int y); 14 void info(); 15 void update_odometers(int o); 16 ~Car(){ 17 }; 18 }; 19 Car::Car(string ma,string mo,int y):maker(ma),model(mo),year(y),odometers(0){ 20 } 21 void Car::info(){ 22 cout<<setiosflags(ios::left); 23 cout<<setw(15)<<"maker:"<<maker<<endl; 24 cout<<setw(15)<<"model:"<<model<<endl; 25 cout<<setw(15)<<"year:"<<year<<endl; 26 cout<<setw(15)<<"odometers:"<<odometers<<endl; 27 } 28 void Car::update_odometers(int o){ 29 if(o<odometers) 30 { 31 cout<<"更新数值有误!"<<endl; 32 } 33 else 34 { 35 odometers=o; 36 } 37 } 38 #endif
运行结果:
实验任务四
- pets.hpp
1 #ifndef PETS_HPP 2 #define PETS_HPP 3 #include <iostream> 4 using namespace std; 5 class MachinePets{ 6 private: 7 string nickname; 8 public: 9 MachinePets(const string s):nickname(s){ 10 }; 11 string get_nickname() const{return nickname;}; 12 virtual string talk(){ 13 }; 14 ~MachinePets(){ 15 }; 16 }; 17 class PetCats:public MachinePets{ 18 public : 19 PetCats(const string s):MachinePets(s){ 20 }; 21 string talk(){ 22 return "miao wu~"; 23 } 24 }; 25 class PetDogs:public MachinePets{ 26 public : 27 PetDogs(const string s):MachinePets(s){ 28 }; 29 string talk(){ 30 return "wang wang~"; 31 } 32 }; 33 #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 }
运行结果: