實驗四:繼承
阿新 • • 發佈:2021-11-28
1.實驗任務2
程式原始碼如下:
1 #include <iostream> 2 #include<typeinfo> 3 4 class Graph{ 5 public: 6 virtual void draw(){ 7 std::cout<<"Graph::draw():just as an interface\n"; 8 } 9 }; 10 11 class Rectangle : public Graph 12 { 13 public: 14 voidView Codedraw(){ 15 std::cout<<"Rectangle::draw(): programs of draw a rectangle\n"; 16 } 17 }; 18 19 class Circle : public Graph 20 { 21 public: 22 void draw(){ 23 std::cout<<"Circle::draw(): programs of draw a circle\n"; 24 } 25 }; 26 27 voidfun(Graph *ptr){ 28 std::cout << "Pointer type:"<<typeid(ptr).name()<<"\n"; 29 std::cout << "RTTI type:"<<typeid(*ptr).name()<<"\n"; 30 ptr -> draw(); 31 } 32 int main(){ 33 Graph g1; 34 Rectangle r1; 35 Circle c1; 36 g1.draw(); 37 r1.draw();38 c1.draw(); 39 40 std::cout << "\n"; 41 42 r1.Graph::draw(); 43 c1.Graph::draw(); 44 45 std::cout << "\n"; 46 fun(&g1); 47 fun(&r1); 48 fun(&c1); 49 }
修改之前截圖為:
加virtual修改後的執行結果如圖:
歸納總結:
1.可以觀察到執行時ptr成功指向了派生類,但ptr指標本身還是Graph類的。前面的5,6,9數字和字母P是什麼還暫時不知道。
2.當派生類出現與基類同名成員時,會優先執行派生類的函式成員,用二元作用域分辨符標識後可執行基類成員
如r1.Graph::draw(); c1.Graph::draw();
3.型別相容原則:派生類物件可以被當作基類物件使用,但當作基類物件使用時,只能使用作為基類的那一部分介面。因此函式宣告成員型別是Graph,draw()必然顯示是基類。
2.實驗任務3
以下為Battery.hpp
1 #pragma once 2 class Battery { 3 public: 4 int get_capacity() { 5 return capacity; 6 } 7 Battery(int obj = 70):capacity(obj){} 8 private: 9 int capacity; 10 };Battery.hpp
以下為Car.hpp
1 #pragma once 2 #include<iostream> 3 #include<string> 4 using namespace std; 5 class Car { 6 private: 7 string maker; 8 string model; 9 int year; 10 int odometers; 11 public: 12 Car(); 13 Car(string m1, string m2, int y) :maker(m1), model(m2), year(y), odometers(0) {}; 14 void info(); 15 void update_odometers(int n); 16 }; 17 void Car::info() { 18 cout << maker << endl; 19 cout << model << endl; 20 cout << year << endl; 21 cout << odometers << endl; 22 } 23 void Car::update_odometers(int n) { 24 if (n >= odometers) 25 odometers = n; 26 else 27 cout << "data is error!"; 28 }Car.hpp
以下為ElectricCar.hpp
ElectricCar.hpp以下為task3.cpp
1 #include <iostream> 2 #include "electricCar.hpp" 3 4 int main() 5 { 6 using namespace std; 7 8 // test class of Car 9 Car oldcar("Audi", "a6", 2016); 10 cout << "--------oldcar's info--------" << endl; 11 oldcar.update_odometers(25000); 12 oldcar.info(); 13 14 cout << endl; 15 16 // test class of ElectricCar 17 ElectricCar newcar("Tesla", "model s", 2016); 18 newcar.update_odometers(12500); 19 cout << "\n--------newcar's info--------\n"; 20 newcar.info(); 21 }View Code
3.實驗任務四
pets.hpp
1 #pragma once 2 #include<string> 3 #include<iostream> 4 using namespace std; 5 class MachinePets { 6 private: 7 string nickname; 8 public: 9 MachinePets(); 10 MachinePets(const string s):nickname(s){} 11 const string get_nickname() { 12 return nickname; 13 } 14 virtual string talk() { 15 return"talk~"; 16 } 17 }; 18 class PetCats : public MachinePets{ 19 public: 20 PetCats(const string st):MachinePets(st){} 21 string talk() { 22 return "miao wu~"; 23 } 24 }; 25 class PetDogs :public MachinePets{ 26 public: 27 PetDogs(); 28 PetDogs(const string s1):MachinePets(s1){ 29 30 } 31 string talk() { 32 return "wang!wang!"; 33 } 34 };View Code
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 }View Code
測試截圖如下:
歸納總結:
1.可以觀察到執行時ptr成功指向了派生類,但ptr指標本身還是Graph類的。前面的5,6,9數字和字母P是什麼還暫時不知道。
2.當派生類出現與基類同名成員時,會優先執行派生類的函式成員,用二元作用域分辨符標識後可執行基類成員
如r1.Graph::draw(); c1.Graph::draw();
3.型別相容原則:派生類物件可以被當作基類物件使用,但當作基類物件使用時,只能使用作為基類的那一部分介面。因此函式宣告成員型別是Graph,draw()必然顯示是基類
4.用typeid().name()獲取型別名
5.在繼承類中初始化時,建構函式放在大括號前面,不然會出現重定義的問題。