Классы, наследование, полиморфизм. Синтаксис объявления производного класса. Конструктор и деструктор производного класса

Страницы работы

Фрагмент текста работы

Point3(double bx,double by,double bz):Point1(bx),Point2(by)

          {z=bz;}

    ~Point3 ()                                      //  деструктор

          { cout << "destructor Point3 done"<<endl;}

      void Print ()

       {   cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}

};

void main()               

   Point3 P(1,2,3);

   P.Print();                   //    1 2 3

}


ПРИМЕР 6. Множественное наследование. Неопределенность

Пример множественного наследования вида:

                    Point1          Point2

                         

                               Point3

В каждом базовом классе есть свой метод Print. В производном классе такой метод отсутствует. При вызове метода Print из базового класса возникает неопределенность!

#include <iostream.h>

class  Point1                //   объявление 1 базового класса

   protected:   double x;           

   public:                           

    Point1(double bx=0)     //  конструктор

          {x=bx; }

    ~Point1 ()                                      //  деструктор

          { cout << "destructor Point1 done"<<endl;}

     void Print ()

            {cout <<" x="<<x<<endl;}

};

class  Point2    //   объявление 2 базового класса 

{ protected:     double y;             

   public:                           

        Point2(double by)        //  конструктор

          {y=by;}

    ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

     void Print ()

        {cout <<"  y="<<y<<endl;}

};

class  Point3: public Point1, public Point2  

{ double z;              

   public:                

                     //  конструктор вызывает конструкторы 2 базовых классов

    Point3(double bx,double by,double bz):Point1(bx),Point2(by)

          {z=bz;}

    ~Point3 ()                                      //  деструктор

          { cout << "destructor Point3 done"<<endl;}

      void Print3 ()

       {   cout<<" z="<<z<<endl;}

};

void main()               

   Point3 P(1,2,3);

   //  P.Print();                   //    !!! неопределенность

   P.Point1::Print();                //  1

   P.Point2::Print();               //  2

   P.Print3();                          //  3

}

ПРИМЕР 7. Полиморфизм. Переопределение метода

Базовый класс имеет метод Print. Производный класс имеет свой метод Print. Поля базового класса имеют доступ protected.

#include <iostream.h>

class  Point1                //   объявление класса

{  protected:   double x,y;          

   public:                           

    Point1(double bx=0, double by=0)     //  конструктор

          {x=bx; y=by; }

    ~Point1 ()                                               //  деструктор

          { cout << "destructor Point1 done"<<endl;}

      void Print ()

            {cout <<" x="<<x<<"  y="<<y<<endl;}

};

class  Point2: public Point1   //   объявление класса наследника

{                                //  по умолчанию спецификатор доступа private

     double z;              

   public:                           

        Point2(double bx,double by, double bz):Point1(bx,by)        //  конструктор

          {z=bz;}

    ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

              //   метод переопределен: обращение к полям базового класса

void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" z="<<z<<endl;}

};

void main()               

   Point1 P1(1,2);

   P1.Print();                     // 1 2

   Point2 P2(1,2,3);

   P2.Print();                        //  1 2 3

   P3.Point1::Print();           // 1 2        !!!    вызов метода базового класса

}


ПРИМЕР 8. Динамические объекты через указатель на базовый класс.

Два производных класса от одного базового.

                            Point1

                       Point2    Point3

В каждом классе свой метод Print.

В главной программе определим динамические объекты, через указатель на базовый класс. При вызове метода Print для объектов производных классов, происходит вызов метода базового (!) класса.

#include <iostream.h>

class  Point1                             //   объявление базового класса

{     protected:      

         double x,y;          

   public:                           

    Point1(double bx=0, double by=0)     //  конструктор

          {x=bx; y=by; }

    ~Point1 ()                                      //  деструктор

          { cout << "destructor Point1 done"<<endl;}

     void Print ()

            {cout <<" x="<<x<<"  y="<<y<<endl;}

};

class  Point2: public Point1          //   объявление класса наследника

{  double z;              // новое поле

   public:                           

        Point2(double bx,double by, double bz):Point1(bx,by)        //  конструктор

          {z=bz;}

    ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

                                      //   метод переопределен

     void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" z="<<z<<endl;}

};

class  Point3: public Point1            //   объявление класса наследника

{    int a,b;                        //  новые поля

   public:                           

        Point3(double bx,double by, int ba,int bb):Point1(bx,by)        //  конструктор

          {a=ba;b=bb;}

    ~Point3 ()                                      //  деструктор

          { cout << "destructor Point3 done"<<endl;}

                                             //   метод переопределен

     void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" a="<<a<<"  b="<<b<<endl;}

};

void main()               

{

  Point1* P;

   P=new Point1(1,2);                  

   P->Print();                           //  1 2

     // Указатель на базовый класс совместим с указателем на производный класс.

   P=new Point2(3,4,5);  

   P->Print();                            //  3 4  !!!

     // Указатель на базовый класс совместим с указателем на производный класс.

   P=new Point3(6,7,8,9);        //   

   P->Print();                            // 6 7   !!!

}


ПРИМЕР 9. Динамические объекты через указатель на базовый класс. Виртуальные функции

Пример тот же. Добавляем одно слово virtual для метода Print базового класса!

Для каждого объекта производных классов вызывается свой метод Print.

#include <iostream.h>

class  Point1                //   объявление базового класса

{     protected:      

         double x,y;          

   public:                           

    Point1(double bx=0, double by=0)     //  конструктор

          {x=bx; y=by; }

    ~Point1 ()                                      //  деструктор

          { cout << "destructor Point1 done"<<endl;}

     virtual void Print ()

            {cout <<" x="<<x<<"  y="<<y<<endl;}

};

class  Point2: public Point1   //   объявление класса наследника

{  double z;              // новое поле

   public:                           

        Point2(double bx,double by, double bz):Point1(bx,by)        //  конструктор

          {z=bz;}

    ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

                                //   метод переопределен

  /* virtual  */    void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" z="<<z<<endl;}

};

class  Point3: public Point1   //   объявление класса наследника

{    int a,b;                        //  новые поля

   public:                           

        Point3(double bx,double by, int ba,int bb):Point1(bx,by)        //  конструктор

          {a=ba;b=bb;}

    ~Point3 ()                                      //  деструктор

          { cout << "destructor Point3 done"<<endl;}

                                    //   метод переопределен

    /* virtual  */     void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" a="<<a<<"  b="<<b<<endl;}

};

void main()               

{

  Point1* P;

   P=new Point1(1,2);

   P->Print();                              // 1 2

     // Указатель на базовый класс совместим с указателем на производный класс.

   P=new Point2(3,4,5);

   P->Print();                               // 3 4 5        !!!

     // Указатель на базовый класс совместим с указателем на производный класс.

   P=new Point3(6,7,8,9);

   P->Print();                                 //  6 7 8 9       !!!

}


ПРИМЕР 10. Абстрактный класс

Пример тот же. Базовый класс – абстрактный.

#include <iostream.h>

class  Point                //   объявление абстрактного класса

   public:                           

     Point() {}     //  конструктор

      ~Point () {}                              //  деструктор

     virtual void Print() =0;           // чистая виртуальная функция

};

class  Point1: public Point        //   объявление производного класса 

{ protected:     double x;             

   public:                           

        Point1(double bx)   {x=bx;}                 //  конструктор

      ~Point1 ()                                              //  деструктор

          { cout << "destructor Point1 done"<<endl;}

     void Print ()        {cout <<"  x="<<x<<endl;}

};

class  Point2: public Point1   //   объявление производного класса 

{ double y;              

   public:                

    Point2(double bx,double by):Point1(bx)    {y=by;}      //  конструктор

   ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

     void Print()     {cout <<" x= "<<x<<"  y="<<y<<endl;}

};

void main()               

{   Point* P;

//   P=new Point();            //  !!! нельзя создать объект абстрактного класса

//   P->Print();

   P=new Point1(1);

   P->Print();                           // 1

   P=new Point2(2,3);

   P->Print();                            //  2  3

}


ПРИМЕР 11. Вызов метода производного класса из  метода базового класса

Два производных класса от одного базового.

                            Point1

                       Point2    Point3

В каждом классе свой метод Print, который должен вызываться из метода Print_B базового класса.

Но при вызове метода Print для объектов производных классов, происходит вызов метода Print базового (!) класса.

#include <iostream.h>

class  Point1                //   объявление базового класса

{     protected:      

         double x,y;          

   public:                           

    Point1(double bx=0, double by=0)     //  конструктор

          {x=bx; y=by; }

    ~Point1 ()                                      //  деструктор

          { cout << "destructor Point1 done"<<endl;}

                                     // вызов метода  Print из метода Print_B

void Print_B()

            {cout <<"  base class  "<<endl;  

              Print();  }     

 void Print ()

            {cout <<" x="<<x<<"  y="<<y<<endl;}

};

class  Point2: public Point1   //   объявление класса наследника

{  double z;              // новое поле

   public:                            

        Point2(double bx,double by, double bz):Point1(bx,by)        //  конструктор

          {z=bz;}

    ~Point2 ()                                      //  деструктор

          { cout << "destructor Point2 done"<<endl;}

                                   //   метод переопределен

   void Print ()     

       { cout<<" x="<<x<<"  y="<<y<<" z="<<z<<endl;}

};

class  Point3: public Point1   //   объявление класса наследника

Похожие материалы

Информация о работе

Тип:
Методические указания и пособия
Размер файла:
384 Kb
Скачали:
0