Шпаргалка по "Программированию"

Автор: Пользователь скрыл имя, 08 Ноября 2011 в 12:07, шпаргалка

Краткое описание

Работа содержит ответы на вопросы по дисциплине "Программирование".

Файлы: 1 файл

default.doc

— 264.50 Кб (Скачать)

                return;

             }

             strcpy(fak,FAK);

          }

          ~grup()

          { cout << "деструктор класса grup " << endl;

    delete fak;

          }

         virtual void see(void);          // объявление виртуальной функции 

};

class stud : public grup               // производный класс 

{      char *fam;                    //  фамилия  

        int oc[4];                      //  массив оценок

public: 

        stud(char *FAK,long GR,char *FAM,int OC[]): grup(FAK,GR)

        { if (!(fam=new char[20])) 

           { cout<<"ошибка выделения памяти"<<endl;

              return;

           }

           strcpy(fam,FAM);

           for(int i=0;i<4;oc[i]=OC[i++]);

         }

         ~stud()

         { cout << "деструктор класса stud " << endl;

            delete fam;

         }

         void see(void);

};

void grup::see(void)      // описание виртуальной функции       

{ cout << fak << gr << endl;}

void stud::see(void)      // 

{ grup ::see();                // вызов функции базового класса 

   cout <<setw(10) << fam << "  ";

   for(int i=0; i<4; cout << oc[i++]<<’ ’);

   cout << endl;

}

int main()

{ int OC[]={4,5,5,3};

   grup gr1("факультет 1",123456), gr2("факультет 2",345678), *p;

   stud st("факультет  2",150502,"Иванов",OC);

   p=&gr1;            // указатель на объект базового  класса 

   p->see();           // вызов функции базового класса объекта gr1

   (&gr2)->see();  // вызов функции базового класса  объекта gr2

   p=&st;              // указатель на объект производного  класса 

   p->see();         // вызов функции производного  класса объекта st

   return 0;

}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

35.Множественное  наследование.

В  языке  С++  имеется  возможность  образовывать  производный  класс  от

нескольких базовых  классов. Общая форма множественного наследования имеет вид class  имя_произв_класса : имя_базового_кл 1,…,имя_базового_кл N { содержимое класса };

Иерархическая структура, в которой производный  класс наследует от не-

скольких  базовых  классов, называется множественным  наследованием. В  этом случае  производный  класс,  имея  собственные  компоненты,  имеет  доступ  к protected- и public-компонентам базовых классов.

Конструкторы  базовых классов при создании объекта производного клас-

са вызываются в том порядке, в котором они  указаны в списке при объявлении производного класса. При применении множественного наследования возможно возникновение нескольких  конфликтных  ситуаций. Первая −  конфликт имен методов или  атрибутов нескольких базовых классов:

class A

{public: void fun(){}

};

class B

{public: void fun(){}

};

class C : public A, public B

{ };

int main()

{ C *c=new C;

   c->fun();         //  error C::f' is ambiguous

   return 0;

}

При  таком  вызове функции  fun() компилятор не может  определить, к ка-

кой из двух функций  классов A и B выполняется обращение. Неоднозначность можно  устранить,  явно  указав,  какому из базовых классов принадлежит вызываемая функция: c->A:: fun(); или c->B::fun();

Вторая  проблема  возникает  при  многократном  включении  некоторого

базового класса:

#include <iostream>

using namespace std;

#include <string.h>

class A                                    // базовый класс  I уровня

{     char naz[20];           //  название фирмы 

  public: 

      A(char *NAZ) {strcmp(naz,NAZ);} 

       ~A() {cout << "деструктор класса А" << endl;}

           void a_prnt() {cout << naz << endl;} 

};

class B1 : public A                // производный класс (1 Базовый  II уровня)

{ protected: 

         long tn;      

         int nom;     

   public: 

        B1(char *NAZ,long TN,int NOM): A(NAZ),tn(TN),nom(NOM) {}; 

         ~B1() {cout << "деструктор класса В1" << endl;}

        void b1_prnt()

        {  A::a_prnt();

           cout << " таб. N " << tn <<"  подразделение = " << nom <<endl;

             } 

};

class B2 : public A               // производный класс (2 Базовый  II уровня)

{ protected: 

        double  zp;     

  public: 

        B2(char *NAZ,double ZP): A(NAZ),zp(ZP) {};

        ~B2(){cout << "деструктор класса В2" << endl;}

         void b2_prnt()

         { A::a_prnt();

            cout << " зар/плата = " << zp << endl;

         } 

};

class C : public B1, public B2   // производный класс ( III уровня)

{       char *fam;      

  public: 

         C(char *FAM,char *NAZ,long TN,int NOM,double ZP) : 

         B1(NAZ,TN,NOM), B2(NAZ,ZP) 

         {  fam = new char[strlen(FAM)+1]

             strcpy(fam,FAM);

         }; 

          ~C() {cout << "деструктор класса С" << endl;}

          void c_prnt()

         { B1::b1_prnt(); 

            B2::b2_prnt();

            cout << " фамилия " << fam<<endl;

         } 

};

int main()

{ C cc("Иванов","мастра",1234,2,555.6),*pt=&cc;

//  cc.a_prnt();         ошибка     'C::a_prnt' is ambiguous

//  pt->a_prnt();        

   cc.b1_prnt();

   pt->b1_prnt();

   cc.b2_prnt();

   pt->b2_prnt();

   cc.c_prnt();

   pt->c_prnt();

    return 0;

}

В приведенном  примере производный класс С  имеет по цепочке два оди-

наковых базовых  класса А (A<-B1<-C  и A<-B2<-C), для  каждого базового класса А строится свой объект (рис. 3, 4). Таким образом, вызов функции 

cc.a_prnt();    pt->a_prnt();некорректен, так как неизвестно, какую из двух функций (какого из двух классов А) требуется вызвать.

 
 
 

36.Множественное  наследование и  виртуальные базовые  классы

Если базовый  класс (в приведенном выше примере  это класс А) является

виртуальным, то будет построен единственный объект этого класса.

#include <iostream.h>   

using namespace std;

class A                                  // базовый виртуальный класс  

{    int aa;       

public: 

      A() {cout<<"Конструктор1 класса A"<<endl;} 

      A(int AA) : aa(AA) {cout<<"Конструктор2 класса A"<<endl;}

       ~A() {cout<<"Деструктор класса A"<<endl;}

};

class B : virtual public A     // производный класс (первый базовый  для D)

{   char bb; 

   public: 

      B() {cout<<"Конструктор1 класса B"<<endl;}

      B(int AA,char BB): A(AA), bb(BB)

      {cout<<"Конструктор2 класса B"<<endl;} 

     ~B() {cout<<"Деструктор класса B"<<endl;}

};

class C : virtual public A     // производный класс (второй базовый  для D)

{    float cc;

   public: 

      C() {cout<<"Конструктор1 класса C"<<endl;}

      C(int AA,float CC) : A(AA), cc(CC)

      {cout<<"Конструктор2 класса C"<<endl;}

      ~C() {cout<<"Деструктор класса C"<<endl;}

};

class D : public C,public B  // производный класс (II уровня)

{     int dd;

public: 

       D() {cout<<"Конструктор 1 класса D"<<endl;}

       D(int AA,char BB,float CC,int DD) : 

          A(AA), B(AA,BB), C(AA,CC), dd(DD) 

        {cout<<"Конструктор 2 класса D"<<endl;}

       ~D() {cout<<"Деструктор класса D"<<endl;}

};

void main()

{ D d(1,'a',2.3,4); 

  D dd;

}

Результат работы программы:

Конструктор 2 класса A                        (конструкторы для объекта d)

Конструктор 2 класса C

Конструктор 2 класса B

Конструктор 2 класса D

Конструктор 1 класса A                        (конструкторы для объекта dd)

Конструктор 1 класса C

Конструктор 1 класса B

Конструктор 1 класса D

Деструктор класса D                             (деструкторы для объекта d)

Деструктор класса B

Деструктор класса C

Деструктор класса A

Деструктор класса D                             (деструкторы для объекта d)

Деструктор класса B

Деструктор класса C

Деструктор класса A

Виртуальный базовый  класс всегда инициализируется только один раз. В 

примере  при  создании  объектов  d  и  dd  конструктор  класса  А  вызывается  из конструктора класса D первым и только один раз, затем  конструкторы классов B и C, в том порядке, в котором они описаны в строке наследования классов: class D : public B, public C  . В одно и то же время класс может иметь виртуальный и невиртуальный базовые классы, например:

class A{ … };

class B1: virtual public A{ … };

class B2: virtual public A{ … };

class B3: public A{ …  };

class C:  public B1, public B2, public B3 { … };

В этом случае класс  С имеет два подобъекта класса А, один наследуемый 

через классы В1 и В2 (общий для этих классов) и  второй через класс В3 . 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

37.Абстрактные  классы .

Информация о работе Шпаргалка по "Программированию"