实验四 类的继承
一、
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); }
运行结果截图:
对基类draw()成员函数使用“virtual”关键字后运行结果截图:
归纳总结:
类型兼容原则:通过公有继承,除构造函数,析构函数,私有成员不能继承外,公有派生类具备了基类的所有功能,凡是基类能解决的问题,派生类都能解决。
同名覆盖原则:只有在相同作用域中定义的函数才可以重载,所以若子类中声明了与父类成员函数同名的新函数,即使参数表不同,父类中所有继承的同名重载函数都被隐藏。
二元作用域分辨符:“::”用来限定所要访问成员所在的类的名称。通过此符号明确的标识了派生类中由基类继承来的成员,达到访问的目的,解决成员被隐藏的问题。
task2中加入“virtual"关键字后,基类和派生类中的同名函数都定义成虚函数,并获得不同的地址值。每个类的对象获得了相应的地址,从而访问相应的成员函数,实现多态性。若不加关键字"virtual",由于在c++中派生类元素在内存中堆放是:前N个是基类的元素,N之后的是派生类的元素,所以派生类的基类指针或引用只能访问到基类的元素而不能访问派生类的元素。
二、
task3.cpp源码:
#include <iostream> #include "electricCar.hpp" int main() { using namespace std; // test class of Car Car oldcar("ASS", "BT", 2060); cout << "--------oldcar's info--------" << endl; oldcar.update_odometers(25120); oldcar.info(); cout << endl; // test class of ElectricCar ElectricCar newcar("GTR", "CT", 2166); newcar.update_odometers(2520); cout << "\n--------newcar's info--------\n"; newcar.info(); }
electricCars.hpp源码:
#include<iostream> #include<string> #include "battery.hpp" #include "car.hpp" using namespace std; class ElectricCar:public Car{ public: ElectricCar(); ElectricCar(string a,string b,int c,int d=0,int e=70); void info(); private: Battery battery; }; ElectricCar::ElectricCar(string a,string b,int c,int d,int e):Car(a,b,c,d){ battery=e; } void ElectricCar::info (){ cout << left << setw(16) << "maker:" << maker <<endl; cout << left << setw(16) << "model:" << model <<endl; cout << left << setw(16) << "year:" << year <<endl; cout << left << setw(16) << "odometers:" << odometers <<endl; cout << left << setw(16) << "capacity:" << battery.capacity << "-kWh" <<endl; }
Car.hpp源码:
#include<iostream> #include<string> #include<iomanip> using namespace std; class Car{ public: Car(string a,string b,int c,int d=0); void info(); void update_odometers(int d); string maker,model; int year,odometers; }; Car::Car(string a,string b,int c,int d){ maker=a,model=b; year=c,odometers=d; } void Car::info(){ cout << left << setw(16) << "maker:" << maker <<endl; cout << left << setw(16) << "model:" << model <<endl; cout << left << setw(16) << "year:" << year <<endl; cout << left << setw(16) << "odometers:" << odometers <<endl; } void Car::update_odometers(int d){ if(d<odometers) cout << "thereisdefualtintthisdata" <<endl; else odometers=d; }
Battery源码:
#include<iostream> #include<string> using namespace std; class Battery{ public: Battery(int a=70); int get_capacity(){return capacity;} int capacity; }; Battery::Battery(int a){ capacity=a; }
运行结果截图:
三、
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); }
MachinePets.hpp源码:
#include<iostream> #include<string> using namespace std; class MachinePets{ public: MachinePets(const string s); virtual string talk(){return 0;} string get_nickname(); private: string nickname; }; MachinePets::MachinePets(const string s){ nickname=s; } string MachinePets::get_nickname(){ return nickname; } class PetCats:public MachinePets{ public: PetCats(const string s); string talk(); }; PetCats::PetCats(const string s):MachinePets(s){} string PetCats::talk(){ string cats; cats="miao wu~"; return cats; } class PetDogs:public MachinePets{ public: PetDogs(const string s); string talk(); }; PetDogs::PetDogs(const string s):MachinePets(s){} string PetDogs::talk(){ string dogs; dogs="wang wang~"; return dogs; }
运行结果截图: