• 2013级C++第14周(春)项目——多态性、虚函数和抽象类


    课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接


    第一部分 阅读程序
    1、阅读、改动和执行关于交通工具类的程序,回答问题,以理解相关技术方法
    (1)请写出程序的执行结果,并在上机时对比理解

    #include <iostream>
    using namespace std;
    class Vehicle  //交通工具
    {
    public:
        void run() const
        {
            cout << "run a vehicle. "<<endl; 
        }
    };
    class Car: public Vehicle  //汽车
    {
    public:
        void run() const
        {
            cout << "run a car. "<<endl;
        }
    };
    class Airplane: public Vehicle  //飞机
    {
    public:
        void run() const
        {
            cout << "run a airplane. "<<endl;
        }
    };
    int main()
    {
        cout<<"(a) 直接用对象訪问成员函数: "<<endl;
        Vehicle v;
        v.run();
        Car car;
        Airplane airplane;
        car.run();
        airplane.run();
        cout<<"(b)用指向基类的指针訪问成员函数: "<<endl;
        Vehicle *vp;
        vp=&car;
        vp->run();
        vp=&airplane;
        vp->run();
        return 0;
    }
    请回答:当基类的指针指向派生类时。用指针调用同名成员函数,执行的是基类的成员函数,还是派生类的成员函数?为什么会这样?

    (2)假设将Vehicle类的定义改动为虚函数。其余不变。请写出程序的执行结果,并在上机时对比理解

    class Vehicle {
    public: 
        virtual void run() const { cout << "run a vehicle. "<<endl; } //(2) run()为虚函数
    };
    请回答:当基类的指针指向派生类时,用指针调用同名虚成员函数,执行的是基类的成员函数,还是派生类的成员函数?为什么会这样?什么是多态性?请结合本例的执行结果说明。


    (3)假设将Vehicle类的定义改动为纯虚函数,找出main()函数中将使编译出错的行删除(或改为凝视)。请写出程序的执行结果。并在上机时对比理解

    class Vehicle{
    public: 
        virtual void run() const = 0; //(3) run()为纯虚函数。const意指其为常成员函数。并不是纯虚函数之必要
    }; 
    请回答:当基类同名成员函数定义为纯虚函数后,发生了什么现象?为什么会这样?

    (4)提交博文,记录实验过程和结果,用自己的话回答上面提出的问题,概括你对虚函数、多态性和抽象类的理解。——不要忽视回答问题,写出来,你会更明确。

    2、阅读以下的程序,并写出执行结果
    (1)

    #include <iostream>
    using namespace std;
    class BASE
    {
    private:
        char c;
    public:
        BASE(char n):c(n) {}
        virtual ~BASE()
        {
            cout<<c;
        }
    };
     
    class DERIVED:public BASE{
    private:
        char c;
    public:
        DERIVED(char n):BASE(n+1),c(n) {}
        ~DERIVED()
        {
            cout<<c;
        }
    };
    int main(){
        DERIVED d('X');
        return 0;
    }  

    (2)
    #include <iostream>
    using namespace std;
    class Mammal
    {
    public:
      Mammal( ){
        cout<<"Mammal constructor called."<<endl;
      }
      virtual ~Mammal(){
        cout<<"Mammal destructor called."<<endl;
      }
      virtual void Speak() const{
        cout<<"Mammal speak."<<endl;
      }
    };
      
    class Dog : public Mammal{
    public:
      Dog(){
        cout<<"Dog constructor called."<<endl;
      }
      ~Dog(){
        cout<<"Dog destructor called."<<endl;
      }
      void Speak() const{
        cout<<"Woof!"<<endl;
      }
    };
    int main(){
      Mammal *p=new Dog;
      p->Speak();
      delete p;
      return 0;
    }

    第二部分 实践项目
    【项目1-动物这样叫】以下是给出的基类Animal声明和main()函数。


    class Animal
    {
    public:
      virtual void cry()
        {
          cout<<"不知哪种动物,让我怎样学叫?"<<endl;
        }
    };
    
    int main( ){
        Animal *p;
        p = new Animal();
        p->cry(); 
        Mouse m1("Jerry",'m'); 
        p=&m1;
        p->cry(); 
        Mouse m2("Jemmy",'f');
        p=&m2;
        p->cry(); 
        Cat c1("Tom");
        p=&c1;
        p->cry(); 
        Dog d1("Droopy");
        p=&d1;
        p->cry(); 
        Giraffe g1("Gill",'m');
        p=&g1;
        p->cry(); 
        return 0;
    }
      程序的执行结果将是:


      1、依据给出的main()函数和执行结果的提示,设计出相关的各个类。注意观察执行结果。提取出每个类中须要的数据成员,并匹配上须要的成员函数。


      2、显然,Animal设计为抽象类更合适,Animal不须要可以实例化,是专门作基类使用的。

    改造程序,使Animal设计为抽象类,这时main()函数中p = new Animal();将出错。将此行删除。
      3、每个Animal的派生类都有一个“名字”数据成员,这个成员设置为基类Animal的成员更好。改造上面的程序,将“名字”成员作为抽象类Animal数据成员被各派生类使用。
      
    【项目2-形状类族的中的纯虚函数】写一个程序,定义抽象基类Shape。由它派生出3个派生类,Circle(圆形)、Rectangle(矩形)、Triangle(三角形)。用例如以下的main()函数,求出定义的几个几何体的面积和。

     

    int main()
    {
        Circle c1(12.6),c2(4.9);//建立Circle类对象c1,c2,參数为圆半径
        Rectangle r1(4.5,8.4),r2(5.0,2.5);//建立Rectangle类对象r1,r2,參数为矩形长、宽
        Triangle t1(4.5,8.4),t2(3.4,2.8); //建立Triangle类对象t1,t2,參数为三角形底边长与高
        Shape *pt[6]= {&c1,&c2,&r1,&r2,&t1,&t2}; //定义基类指针数组pt,使它每个元素指向一个派生类对象
        double areas=0.0; //areas为总面积
        for(int i=0; i<6; i++)
        {
            areas=areas + pt[i]->area();
        }
        cout<<"totol of all areas="<<areas<<endl;   //输出总面积
        return 0;
    }
    【项目2-平面面积OJ版】请到烟大OJ平台(202.194.119.110)中,完毕编号为2478的题目。




    【项目3-立体类族共同拥有的抽象类】设计一个抽象类CSolid。含实用于求表面积及体积的两个纯虚函数。设计派生类CCube、CBall、CCylinder。分别表示正方体、球体及圆柱体。

    在main()函数中。定义CSolid *p;(p是指向基类的指针,且这个基类是个抽象类)。要求利用这个p指针,可以求出正方体、球体及圆柱体对象的表面积及体积。





    ================= 迂者 贺利坚 CSDN博客专栏=================
    |== IT学子成长指导专栏 专栏文章的分类文件夹(不定期更新) ==|
    |== C++ 课堂在线专栏  贺利坚课程教学链接(分课程年级) ==|
    |== 我写的书——《逆袭大学——传给IT学子的正能量》    ==|
    ===== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 =====



  • 相关阅读:
    Codeforces Gym101502 K.Malek and Summer Semester
    Codeforces Gym101502 J-取数博弈
    Codeforces Gym101502 I.Move Between Numbers-最短路(Dijkstra优先队列版和数组版)
    Codeforces Gym101502 H.Eyad and Math-换底公式
    Codeforces Gym101502 F.Building Numbers-前缀和
    Codeforces Gym101502 B.Linear Algebra Test-STL(map)
    Codeforces Gym101502 A.Very Hard Question
    bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队 分块
    Codeforces Round #250 (Div. 2) D. The Child and Zoo 并查集
    Codeforces Round #250 (Div. 2) A, B, C
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6699167.html
Copyright © 2020-2023  润新知