实验任务二
#程序源码
1 #include <iostream> 2 #include <typeinfo> 3 4 // definitation of Graph 5 class Graph 6 { 7 public: 8 virtual void draw() { std::cout << "Graph::draw() : just as an interface\n"; } 9 }; 10 11 12 // definition of Rectangle, derived from Graph 13 class Rectangle : public Graph 14 { 15 public: 16 void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; } 17 }; 18 19 20 // definition of Circle, derived from Graph 21 class Circle : public Graph 22 { 23 public: 24 void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; } 25 }; 26 27 28 // definitaion of fun(): as a call interface 29 void fun(Graph *ptr) 30 { 31 std::cout << "pointer type: " << typeid(ptr).name() << "\n"; 32 std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; 33 ptr -> draw(); 34 } 35 36 // test 37 int main() 38 { 39 Graph g1; 40 Rectangle r1; 41 Circle c1; 42 43 // call by object name 44 g1.draw(); 45 r1.draw(); 46 c1.draw(); 47 48 std::cout << "\n"; 49 50 // call by object name, and using the scope resolution operator:: 51 r1.Graph::draw(); 52 c1.Graph::draw(); 53 54 std::cout << "\n"; 55 56 // call by pointer to Base class 57 fun(&g1); 58 fun(&r1); 59 fun(&c1); 60 }
调整后:
#归纳总结:
1. 同名覆盖原则:
派生类与基类中有相同成员时:若未强行指名,则通过派生类对象使用的是派生类的同名成员;
如果要通过派生类的对象访问基类被覆盖的同名成员,需要加 对象名.基类名::同名成员 来限定。
2. 二元作用域分辨符:
作用域符号::的前面一般是类名称,后面一般是该类的成员名称,C++为了避免不同的类有名称相同的成员而采用作用域的方式进行区分
3. 类型兼容原则:
类型兼容原则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样公有派生类就具备了基类的所有功能。凡是基类能解决的问题。公有派生类都可以解决。类型兼容原则中所指的替代包括以下情况:
1)子类对象可以当作父类对象使用
2)子类对象可以直接赋值给父类对象
3)子类对象可以直接初始化父类对象
4)父类指针可以直接指向子类对象
5)父类引用可以直接引用子类对象
4. virtual虚函数作用:
基类和子类都有同一个函数,定义一个基类指针指向子类对象,用指针调用该函数,如果函数为非虚则调用基类函数,否则调用子类函数。若指针与指向对象相同,则各自调用各自的函数。将共同的基类作为虚基类,这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样不仅就解决了二义性问题,也节省了内存,避免了数据不一致的问题。
实验任务三
battery.hpp
1 #ifndef BATTERY_HPP 2 #define BATTERY_HPP 3 #include<iostream> 4 #include<string> 5 using namespace std; 6 7 class battery{ 8 public: 9 battery(int capacity = 70): m_capacity{capacity} {} 10 11 int get_capacity() 12 { 13 return m_capacity; 14 } 15 private: 16 int m_capacity; 17 }; 18 19 #endif
car.hpp
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 #include<iostream> 4 #include<string> 5 using namespace std; 6 7 class car{ 8 public: 9 car(string maker, string model, int year, int odometers = 0): m_maker{maker}, m_model{model}, m_year{year}, m_odometers{odometers} {} 10 void info() 11 { 12 cout << "maker: \t" << m_maker << endl; 13 cout << "model: \t" << m_model << endl; 14 cout << "year: \t" << m_year << endl; 15 cout << "odometers:\t" << m_odometers << endl; 16 } 17 18 void update_odometers(int n) 19 { 20 if(n < m_odometers) 21 { 22 cout << "Error updating value" << endl; 23 } 24 else 25 { 26 m_odometers = n; 27 } 28 } 29 30 private: 31 string m_maker; 32 string m_model; 33 int m_year; 34 int m_odometers; 35 }; 36 37 #endif
electricCar.hpp
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 #include<iostream> 4 #include<string> 5 using namespace std; 6 7 class car{ 8 public: 9 car(string maker, string model, int year, int odometers = 0): m_maker{maker}, m_model{model}, m_year{year}, m_odometers{odometers} {} 10 void info() 11 { 12 cout << "maker: \t" << m_maker << endl; 13 cout << "model: \t" << m_model << endl; 14 cout << "year: \t" << m_year << endl; 15 cout << "odometers:\t" << m_odometers << endl; 16 } 17 18 void update_odometers(int n) 19 { 20 if(n < m_odometers) 21 { 22 cout << "Error updating value" << endl; 23 } 24 else 25 { 26 m_odometers = n; 27 } 28 } 29 30 private: 31 string m_maker; 32 string m_model; 33 int m_year; 34 int m_odometers; 35 }; 36 37 #endif
main_car.cpp
#include <iostream> #include "electricCar.hpp" int main() { using namespace std; // test class of Car car oldcar("Audi", "a4", 2016); cout << "--------oldcar's info--------" << endl; oldcar.update_odometers(25000); oldcar.info(); cout << endl; // test class of ElectricCar electricCar newcar("Tesla", "model s", 2020, 0, 150); newcar.update_odometers(5200); cout << "\n--------newcar's info--------\n"; newcar.info(); }
实验任务四
pets.hpp
1 #ifndef MACHINEPETS_HPP 2 #define MACHINEPETS_HPP 3 #include<iostream> 4 #include<string> 5 6 using namespace std; 7 8 class MachinePets 9 { 10 public: 11 MachinePets(const string s): nickname{s} {} 12 13 string get_nickname() 14 { 15 return nickname; 16 } 17 18 virtual string talk() 19 { 20 21 } 22 private: 23 string nickname; 24 }; 25 26 class PetCats: public MachinePets 27 { 28 public: 29 PetCats(const string s) : MachinePets(s) {} 30 string talk() 31 { 32 return "miao wu~ miao wu~ miao wu~" ; 33 } 34 }; 35 36 class PetDogs: public MachinePets 37 { 38 public: 39 PetDogs(const string s) : MachinePets(s) {} 40 string talk() 41 { 42 return "wang wang~ wang wang~ wang wang~" ; 43 } 44 }; 45 #endif
main_pets.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 }