实验四:继承

任务二:

1、

cpp:

#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 arectangle\n"; }
};
// definition of Circle, derived from Graph
class Circle : public Graph
{
public:
  void draw() { std::cout << "Circle::draw(): programs of draw acircle\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);
}

运行结果:

 

2、

cpp:

#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 arectangle\n"; }
};
// definition of Circle, derived from Graph
class Circle : public Graph
{
public:
  void draw() { std::cout << "Circle::draw(): programs of draw acircle\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);
}

运行结果:

 

任务三:

car.hpp:

#include<iostream>
#include<string>
using namespace std;
class Car
{
private: string maker,model;int year,odometers;
public:Car(string x="UNKNOW",string y="UNKNOW",int x1=1000,int y1=0):maker(x),model(y),year(x1),odometers(y1){};
       void info()
       {
           cout<<"maker:\t"<<maker<<endl;
           cout<<"model:\t"<<model<<endl;
           cout<<"year:\t"<<year<<endl;
           cout<<"odometers:\t"<<odometers<<endl;
       }
       void update_odometers(int t)
       {
           if(t<odometers)
               cout<<"data is wrong,please update again\n";
           else 
               odometers=t;
       }
};

 

battery.hpp:

#include<iostream>
#include<string>
using namespace std;
class Battery
{
private: string capacity;
public: Battery(string x="70-kWh"):capacity(x){};
        string get_capacity(){return capacity;};
};

electriccar.hpp:

#include<iostream>
#include<string>
#include"battery.hpp"
#include"car.hpp"
using namespace std;
class ElectricCar:public Car
{
private:Battery battery;
public:ElectricCar(string x="UNKNOW",string y="UNKNOW",int x1=1000,int y1=0,string t="70-kWh"):battery(t),Car(x,y,x1,y1){};
       void info()
       {
           Car::info();
           cout<<"capacity:\t"<<battery.get_capacity()<<endl;
       }
};

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();
}

运行结果:

 

任务四:

pets.hpp:

#include<iostream>
#include<string>
using namespace std;
class MachinePets
{
private:string nickname;
public:MachinePets(const string s):nickname(s){};
       virtual string talk(){return "?";};
       string get_nickname(){return nickname;};
};
class PetCats:public MachinePets
{
public:PetCats(const string s):MachinePets(s){};
       string talk(){return "cant become human";};
};
class PetDogs:public MachinePets
{
public:PetDogs(const string s):MachinePets(s){};
       string talk(){return "failure dog";};
};

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);
}

运行结果:

 

总结:

 任务二:

同名覆盖原则:派生类与基类中有相同成员时,通过派生类对象使用的是派生类的同名成员;

二元作用域分辨符:类名称::成员名,可以精确指定某个成员;

类型兼容原则:在需要基类对象的任何地方都可以使用公有派生类的对象来替代:

    (1)派生类对象可以隐含转化为基类对象,b1=d1;

    (2)派生类的对象可以初始化基类的引用,B &rb=d1;

    (3)派生类的指针可以隐含转化为基类的指针,pb1=&d1;

对于某个基类的多次引用,我们更推荐用virtual定义,这样可以让每个派生类对于同一函数拥有不同空间,更便于管理,避免基类中的某些函数在引用过程中不会产生歧义报错

任务三是很普通的类的定义,主要加强了对继承的应用

任务四就是对任务二的理解,virtual使得两个派生类都能够返回自己定义函数值

 

posted @ 2021-11-29 19:52  在野车辙  阅读(6)  评论(3编辑  收藏  举报