1. 程式人生 > 其它 >實驗四:繼承

實驗四:繼承

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         void
draw(){ 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 void
fun(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 }
View Code

修改之前截圖為:

加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.在繼承類中初始化時,建構函式放在大括號前面,不然會出現重定義的問題。