实验四 继承
任务二
task2:
#include <iostream> #include <typeinfo> // definitation of Graph class Graph { public: void draw() { std::cout << "Graph::draw() : just as an interface\n"; } }; // definition of Rectangle, derived from Graph class Rectangle : public Graph { public: void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; } }; // definition of Circle, derived from Graph class Circle : public Graph { public: void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; } }; // definitaion of fun(): as a call interface void fun(Graph *ptr) { std::cout << "pointer type: " << typeid(ptr).name() << "\n"; std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; ptr -> draw(); } // test int main() { Graph g1; Rectangle r1; Circle c1; // call by object name g1.draw(); r1.draw(); c1.draw(); std::cout << "\n"; // call by object name, and using the scope resolution operator:: r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; // call by pointer to Base class fun(&g1); fun(&r1); fun(&c1); }
测试截图:
微调代码后:
#include <iostream> #include <typeinfo> // definitation of Graph class Graph { public: virtual void draw() { std::cout << "Graph::draw() : just as an interface\n"; } }; // definition of Rectangle, derived from Graph class Rectangle : public Graph { public: void draw() { std::cout << "Rectangle::draw(): programs of draw a rectangle\n"; } }; // definition of Circle, derived from Graph class Circle : public Graph { public: void draw() { std::cout << "Circle::draw(): programs of draw a circle\n"; } }; // definitaion of fun(): as a call interface void fun(Graph *ptr) { std::cout << "pointer type: " << typeid(ptr).name() << "\n"; std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; ptr -> draw(); } // test int main() { Graph g1; Rectangle r1; Circle c1; // call by object name g1.draw(); r1.draw(); c1.draw(); std::cout << "\n"; // call by object name, and using the scope resolution operator:: r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; // call by pointer to Base class fun(&g1); fun(&r1); fun(&c1); }
测试截图
归纳总结:
同名覆盖原则:
派生类与基类中有相同成员时:
若未强行指名,则通过派生类对象使用的是派生类的同名成员;
二元作用域分辨域:
::作二元作用域分辨符的用法是:类名::成员
类型兼容原则:
1.派生类的对象可以隐含转换为基类的对象。
2.派生类的对象可以初始化基类的引用。
3.派生类的指针可以隐含转化为基类的指针。
在替代之后,派生类的对象就可以作为基类的对象使用,但只能使用从基类继承
任务三
Battary.hpp
#ifndef BATTARY_HPP #define BATTARY_HPP using namespace std; class Battary { public: Battary(int c0 = 70):capacity(c0){}; ~Battary(){}; int get_capacity(){return capacity;}; private: int capacity; }; #endif
Car.hpp
#ifndef CAR_HPP #define CAR_HPP #include <iostream> #include <string> #include <iomanip> using namespace std; class Car { public: Car(string m1,string m2,int y,int o = 0):maker{m1},model{m2},year{y},odometers{o}{}; ~Car(){}; virtual void info(); void update_odometers(int o1); private: string maker; string model; int year; int odometers; }; void Car::info() { cout<<"maker: "<<setiosflags(ios::left)<<setw(10)<<maker<<endl; cout<<"model: "<<setw(10)<<model<<endl; cout<<"year: "<<setw(10)<<year<<endl; cout<<"odometers: "<<setw(10)<<odometers<<endl; } void Car::update_odometers(int o1) { if(o1<odometers) cout<<"Error!!!!"; else odometers = o1; } #endif
ElectricCar.hpp
#ifndef ELECTRICAR_HPP #define ELECTRICAR_HPP #include <iostream> #include <string> #include <iomanip> #include "Car.hpp" #include "Battary.hpp" using namespace std; class ElectricCar:public Car { public: ElectricCar(string m1,string m2,int y,Battary b = 70):Car(m1,m2,y,0),battary(b){}; void info(); private: Battary battary; }; void ElectricCar::info() { Car::info(); cout << "capacity: "<<battary.get_capacity()<<"-kWh"<<endl; } #endif
task3.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", 2016); newcar.update_odometers(2500); cout << "\n--------newcar's info--------\n"; newcar.info(); }
运行测试截图
task4
Pets.hpp
#ifndef PETS_HPP #define PETS_HPP #include <string> using namespace std; class MachinePets { public: MachinePets(const string s):nickname(s){}; string get_nickname() const { return nickname; }; virtual string talk(){return "hhhhhhh";}; private: string nickname; }; class PetCats:public MachinePets { public: PetCats(const string s):MachinePets(s){}; string talk(){return "miao!";}; }; class PetDogs:public MachinePets { public: PetDogs(const string s):MachinePets(s){}; string talk(){return "wang!!";}; }; #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); }
运行截图: