实验4 继承
实验任务2
修改前:
#include <iostream> #include <typeinfo> class Graph { public: void draw() { std::cout << "Graph::draw() : just as an interface\n"; } }; class Rectangle : public Graph { public: void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; } }; class Circle : public Graph { public: void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; } }; void fun(Graph *ptr) { std::cout << "pointer type: " << typeid(ptr).name() << "\n"; std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; ptr -> draw(); } int main() { Graph g1; Rectangle r1; Circle c1; g1.draw(); r1.draw(); c1.draw(); std::cout << "\n"; r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; fun(&g1); fun(&r1); fun(&c1); }
运行结果:
修改后:
#include <iostream> #include <typeinfo> class Graph { public: virtual void draw() { std::cout << "Graph::draw() : just as an interface\n"; } }; class Rectangle : public Graph { public: void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; } }; class Circle : public Graph { public: void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; } }; void fun(Graph *ptr) { std::cout << "pointer type: " << typeid(ptr).name() << "\n"; std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; ptr -> draw(); } int main() { Graph g1; Rectangle r1; Circle c1; g1.draw(); r1.draw(); c1.draw(); std::cout << "\n"; r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; fun(&g1); fun(&r1); fun(&c1); }
运行结果:
归纳总结:
1.同名覆盖原则:
若派生类中声明了与基类成员函数同名的新函数,即使函数的参数表不同,从基类继承的同名函数的所有重载形式也都会被隐藏。如果某派生类的多个基类拥有同名的成员,同时,派生类有新增这样的同名成员,这种情况下,派生类成员将隐藏所有基类的同名成员。
2.二元作用域分辨符:
当派生类新增成员隐藏了基类的同名成员,这时使用”对象名.成员名“的访问方式只能访问到派生类新增的成员。对基类同名成员的访问,只能通过基类名和作用域分辨符来实现。
3.类型兼容原则:
类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
实验任务3
Battery.hpp
#ifndef BATTERY #define BATTERY #include<iostream> #include<string> using namespace std; class Battery{ public: Battery(int b=70):capacity(b){}; int get_capacity() const{return capacity;} private: int capacity; }; #endif
Car.hpp
#ifndef CAR #define CAR #include<iostream> #include<string> #include<iomanip> using namespace std; class Car{ public: Car(string s1,string s2,int a,int b=0):maker(s1),model(s2),year(a),odometers(b){}; void info() const { cout<<left<<setw(20)<<"maker: "<<maker<<endl; cout<<left<<setw(20)<<"model: "<<model<<endl; cout<<left<<setw(20)<<"year: "<<year<<endl; cout<<left<<setw(20)<<"odometers: "<<odometers<<endl; } void update_odometers(int meters){ if(meters<odometers) cout<<"The updated number of odometers is wrong."<<endl; else odometers=meters; } private: string maker; string model; int year; int odometers; }; #endif
ElectricCar.hpp
#ifndef ELECTRICCAR #define ELECTRICCAR #include"battery.hpp" #include"car.hpp" #include<iostream> #include<string> #include<iomanip> class ElectricCar:public Car{ public: ElectricCar(string s1,string s2,int a,int b=0,int ca=70):Car(s1,s2,a,b),battery(ca){}; void info() const { Car::info(); cout<<left<<setw(20)<<"capacity: "<<battery.get_capacity()<<"-kWh"<<endl; } private: Battery battery; }; #endif
task3.cpp
#include"electricCar.hpp" #include<iostream> int main(){ using namespace std; Car oldcar("Maserati","Ghibli",2019); cout<<"--------oldcar's info--------"<<endl; oldcar.update_odometers(25000); oldcar.info(); cout<<endl; ElectricCar newcar("BYD", "SUV", 2020); newcar.update_odometers(25000); cout<<"\n--------newcar's info--------\n"; newcar.info(); }
运行结果:
实验任务4
pets.hpp
#ifndef PETS #define PETS #include <iostream> #include <string> using namespace std; class MachinePets{ public: MachinePets(const string s):nickname(s){}; string get_nickname(){return nickname;} virtual string talk() const{ string voice; return voice;} private: string nickname; }; class PetCats: public MachinePets{ public: PetCats(const string s):MachinePets(s){} string talk() const { string voice="miao wu~"; return voice; } }; class PetDogs: public MachinePets{ public: PetDogs(const string s):MachinePets(s){} string talk() const { string voice="wang wang~"; return voice; } }; #endif
task4.cpp
#include <iostream> #include "pets.hpp" void play(MachinePets *ptr) { std::cout << ptr->get_nickname() << " says " << ptr->talk() << std::endl; } int main() { PetCats cat("miku"); PetDogs dog("da huang"); play(&cat); play(&dog); }
运行结果: