Классы. Этапы разработки ООП систем. Дружественные функции и классы. Синтаксис объявления класса

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

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

Статические функции-члены класса имеют доступ  только к статическим членам класса. Для доступа к нестатическим членам они должны получить адрес объекта как параметр

#include <iostream.h>

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

{  

         double m_length;           //  поле -  длина

         double m_width;            //  поле -  ширина  

         double m_height;           //  поле -   высота

         static  int m_noboxes;   //  поле -  cтатическая переменная

   public:                           

    CBox()                             //  конструктор

      {m_length=0; m_width=0; m_height=0; m_noboxes++;}

    CBox(double l,double w)         //  перегруженный конструктор

           {m_length=l; m_width=w; m_height=0; m_noboxes++;}

    CBox(double l, double w, double h)                //  перегруженный конструктор

          {m_length=l; m_width=w; m_height=h; m_noboxes++;}

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

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

     void Set_l(double l)      { m_length=l;}

     void Set_w(double w)   { m_width=w;}

     void Set_h(double h)     { m_height=h;}

      const double Get_l()     { return m_length;} 

      const double Get_w()   { return m_width;}

      const double Get_h()     { return m_height;}

      const void Print ()

            {cout <<" L="<<m_length<<"  W="<<m_width<<" H="<<m_height<<endl;}

      const double Volume( )  {return m_length*m_width*m_height;}

                                //   cтатические функции-члены класса имеют доступ

                                //   только к статическим членам класса.

     static int Getnoboxes() {return m_noboxes;}

                           //  для доступа к нестатическим членам они должны

                           //   получить адрес объекта как параметр

     static int Getnoboxes(CBox & C) {C.Set_l(0);return m_noboxes;}

};

                    //  определение статической переменной обязательно вне класса

int CBox::m_noboxes=0;

        // значение статической переменной в примере равно количеству объектов     

       //  описанного класса

void main()               

    CBox mybox1;                            //  1 объект

    mybox1.Print();

    cout<<mybox1. Getnoboxes ()<<endl;

   CBox mybox2(1,2);                //  2 объект

    mybox2.Print();

    cout<<mybox1. Getnoboxes ()<<endl;

    CBox mybox3(3,4,5);                    //  3 объект

    mybox3.Print();

    cout<<mybox1. Getnoboxes (mybox3)<<endl;

    mybox3.Print();             

}              


ПРИМЕР 8. Массив объектов

Пример тот же. Создаем массив объектов данного класса.

#include <iostream.h>

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

{  

         double m_length;           //  поле -  длина

         double m_width;            //  поле -  ширина  

         double m_height;           //  поле -   высота

         static  int m_noboxes;   //  поле -  cтатическая переменная

   public:                           

    CBox()                             //  конструктор

      {m_length=0; m_width=0; m_height=0; m_noboxes++;}

    CBox(double l,double w)         //  перегруженный конструктор

           {m_length=l; m_width=w; m_height=0; m_noboxes++;}

    CBox(double l, double w, double h)                //  перегруженный конструктор

          {m_length=l; m_width=w; m_height=h; m_noboxes++;}

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

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

     void Set_l(double l)      { m_length=l;}

     void Set_w(double w)   { m_width=w;}

     void Set_h(double h)     { m_height=h;}

      const double Get_l()     { return m_length;} 

      const double Get_w()   { return m_width;}

      const double Get_h()     { return m_height;}

      const void Print ()

            {cout <<" L="<<m_length<<"  W="<<m_width<<" H="<<m_height

                                    << " m_noboxes =  "<<m_noboxes<<endl;   }   

      const double Volume( )  {return m_length*m_width*m_height;}

                                //   cтатические функции-члены класса имеют доступ

                                //   только к статическим членам класса.

     static int Getnoboxes() {return m_noboxes;}

                           //  для доступа к нестатическим членам они должны

                           //   получить адрес объекта как параметр

     static int Getnoboxes(CBox & C) {C.Set_l(0);return m_noboxes;}

};

                    //  определение статической переменной обязательно вне класса

int CBox::m_noboxes=0;

        // значение статической переменной в примере равно количеству объектов     

       //  описанного класса

void main()               

    CBox mybox[4];      //  массив объектов. конструктор по умолчанию!

cout<<"massiv1  "<<endl;

for(int i=0;i<4;i++)

{

cout<<i<<endl;

mybox[i].Print();

}

                                      //  другой массив объектов. инициализация

      CBox mybox1[3];

      mybox1[0]=СBox();

      mybox1[1]=CBox(1,2);

      mybox1[2]=CBox(3,4,5);   

cout<<"massiv2  "<<endl;

for(i=0;i<3;i++)

{ cout<<i<<endl;

mybox1[i].Print();

}

                                      //  или так  массив объектов. инициализация

     CBox mybox2[3]={CBox(),CBox(1,2),CBox(3,4,5)};   

cout<<"massiv3  "<<endl;

for(i=0;i<3;i++)

{ cout<<i<<endl;

mybox2[i].Print();

}

}             

ПРИМЕР 9. Стандартный конструктор копирования

Использование стандартного конструктора копирования.

#include <iostream.h>

class CPoint

{        short   m_a;          // поле  1

          short  m_k;         // поле  2

public:

          CPoint()     {m_a = 4;   m_k = 1;}          // конструктор

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

          void Setk(short k) {m_k=k;}                  // инициализация   поля 2

          void Seta(short a)  {m_a=a;}                  // инициализация поля 1

          void Print ()                                            //  вывод значений полей на экран

                  {cout << " a="<<m_a<<"  k=" << m_k<<endl;}

};

int main()

{

   CPoint  x;          // вызов конструктора – инициализация полей объекта х

   x.Print();           // 4 1             

   CPoint y=x;      // вызов стандартного конструктора  копирования

   y.Print();           // 4 1              

   x.Setk(5);           //   инициализация поля 2

   x.Seta(8);           //  инициализация поля 1

   x.Print();           //  8 5 

   y.Print();           //   4 1

   return 0;            

}                           


ПРИМЕР 10. Стандартный конструктор копирования не работает

Стандартный конструктор копирования нельзя использовать, если Вы работаете с членами – указателями.

#include <iostream.h>

class CPoint

{   short   m_a;          // поле  1

     short   *m_k;         // поле  2          // изменим поле 2

public:

     CPoint()     {m_a=4;   m_k=new short(1);}       // конструктор

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

     void Setk(short k) {*m_k=k;}                // инициализация значения поля 2

     void Seta(short a) {m_a=a;}                  // инициализация поля 1

     void Print ()                                            //  вывод значений полей на экран

               {cout << " a="<<m_a<<"  k=" << *m_k<<”   “<<m_k<<endl;}

};

int main()

{

   CPoint  x;      // вызов конструктора - инициализация полей

   x.Print();       // 4 1            

   CPoint y=x;     // вызов стандартного конструктора  копирования

   y.Print();      // 4 1             

   x.Setk(5);       //   инициализация значения поля 2

   x.Seta(8);       //  инициализация поля 1

   x.Print();       //  8 5 

   y.Print();       //  4 5  !!!   но должно быть 4 1

   return 0;                 

}                      


ПРИМЕР 11. Собственный конструктор копирования

Определение собственного конструктора копирования.

#include <iostream.h>

class CPoint

{   short   m_a;          // поле  1

     short   *m_k;         // поле  2          // изменим поле 2

public:

     CPoint()     {m_a=4;   m_k=new short(1);}        // конструктор

    CPoint ( CPoint  &p)          // собственный конструктор копирования

             {m_a=p.m_a;  m_k=new short(*p.m_k);}   

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

     void Setk(short k) {*m_k=k;}                // инициализация значения поля 2

     void Seta(short a) {m_a=a;}                  // инициализация поля 1

     void Print ()                                            //  вывод значений полей на экран

                  {cout << " a="<<m_a<<"  k=" << *m_k<<”   “<<m_k<<endl;}

};

int main()

{

   CPoint  x;      // вызов конструктора - инициализация полей

   x.Print();       // 4 1            

   CPoint y=x;       // вызов  собственного конструктора  копирования

   y.Print();      // 4 1             

   x.Setk(5);       //   инициализация значения поля 2

   x.Seta(8);       //  инициализация поля 1

   x.Print();       //  8 5 

   y.Print();       //  4  1

   return 0;                 

}                      


ПРИМЕР 12. Вложенные классы

Пример объявление вложенного класса.

#include <iostream.h>

class Outer             //  объявление объемлющего класса

{

class Inner           //  объявление вложенного класса

{

int n;

public:

Inner(){ n=0;}                   // конструктор вложенного класса

int count(){return ++n;}   //  метод вложенного класса

};

Inner n;

public:

int count()  {return n.count();}       //  метод объемлющего класса

};

int main()

{

Outer n;

cout<<n.count()<<endl;                   //  1!!!

// Inner m;                                         //  нельзя!!!

// cout<<m.count()<<endl;   

//  Outer:: Inner m;                                 // нельзя!!!         

//  cout<<m.count()<<endl;                  

return 0;

}


ПРИМЕР 13. Вложенные классы

Пример объявление вложенного класса доступного вне объемлющего класса.

#include <iostream.h>

class Outer             //  объявление объемлющего класса

{

public:

class Inner           //  объявление вложенного класса

{

int n;

public:

Inner(){ n=0;}                   // конструктор вложенного класса

int count(){return ++n;}   //  метод вложенного класса

};

private:

Inner n;

public:

int count()  {return n.count();}       //  метод объемлющего класса

};

int main()

{

Outer n;

cout<<n.count()<<endl;                   // 1!!!

 //Inner m;                                         //  нельзя!!!

 //cout<<m.count()<<endl;   

Outer:: Inner m;                                          

cout<<m.count()<<endl;                   //  1!!!

return 0;

}


 ПРИМЕР 14. Шаблон классов

Шаблон классов для одномерного массива размерности Size.   

#include <iostream.h>

template <class U=int, int Size=100>   // шаблон классов

class MyArray                             //     Объявление класса

{      U m_array [Size];

public:

      MyArray(void)                              //     конструктор

          {for (int i=0; i<=Size-1; i++) m_array[i]=0;}

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

      U Get (int i);                     // метод получения значения i элемента

      void Put (int i, U x);         //  метод инициализации i элемента значением х

      void Print()                       //  метод вывода элементов массива на экран

            {for (int i=0; i<Size; i++) cout << m_array[i] << "   " ; cout<<endl;}

};

                                                           //  Определения методов

template <class U, int Size>            //  шаблон метода 

U  MyArray < U, Size>::Get (int i)       

{    if (i<0) i=0;    if (i>Size-1) i=Size-1;

    return m_array[i];}

template <class U, int Size>                     //  шаблон метода 

void  MyArray < U, Size>::Put (int i, U x)

{  if (i<0) i=0;  if (i>Size-1) i=Size-1;

    m_array[i]=x;

}

int main()

    MyArray <double, 5> darray;  //объект - массив из 5 вещественных элементов

    MyArray <> iarray;                  // объект - массив из 100 целых элементов

     cout<<" darray = "<<endl;    darray.Print();

     cout<<" iarray = "<<endl;    iarray.Print();

    darray.Put(1,3.14);

    iarray.Put(0,2);

    darray.Put(0,iarray.Get(0));

    cout<<" darray = "<<endl;   darray.Print();

    return 0;  

}

ПРИМЕР 15. Перегрузка операторов 

Пример шаблона классов CVecn, позволяющего работать с n-мерными векторами, заданными своими координатами в прямоугольной системе координат. Внутренне представление этого вектора – одномерный массив элементов типа double размером n элементов.

#include <iostream.h>

template <int Size=3>            

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

{  double m_array[Size];                      // массив – поле класса

public:

    CVecn (void) {for (int i=0; i<Size; i++) m_array[i]=0;}      // конструктор

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

    CVecn operator - ();                                                      //  унарный -

    CVecn operator +=(const CVecn &r);       //  сложение векторов с замещением

    CVecn operator +(const CVecn &r);         //  сложение векторов

    CVecn operator -=(const CVecn &r);        //  вычитание векторов с замещением

    CVecn operator -(const CVecn &r);          //  вычитание векторов

    double operator *(const CVecn &r);         //  скалярное произведение

    CVecn operator *(double l);                       //  умножение вектора на скаляр

    friend CVecn operator *(double l,CVecn &r)  //  умножение скаляра на вектор

                         {  return r*l;}

   bool operator ==(const CVecn &r);   // логическая операция равенства векторов

   bool operator !=(const CVecn &r); // логическая операция неравенства векторов

  double& operator [] (const int i);  //  оператор индексирования

                                              //  позволяет обращаться к элементам массива

                                 //  не нужны функции для доступа к полям (типа Set или Get).

};

template <int Size>

CVecn<Size> CVecn<Size>::operator -()             //  унарный -

{   CVecn <Size> Result;

     for (int i=0; i<Size; i++)

               Result.m_array[i] = -m_array[i];

    return Result;

}

template <int Size>

double& CVecn <Size>::operator [](const int i)     

                                               //  оператор индексирования

{   if (i<0)  return m_array[0];

    if (i>=Size)   return m_array[Size-1];

    return m_array[i];

}

template <int Size>                         //  сложение векторов с замещением

CVecn <Size> CVecn <Size>::operator +=(const CVecn<Size> &r)

{   for (int i=0; i<Size; i++)

               m_array[i] += r.m_array[i];

    return *this;

}

template <int Size>                                   //  сложение векторов

CVecn <Size> CVecn <Size>::operator +(const CVecn<Size>& r) 

{   CVecn <Size> Rezult;

    for (int i=0; i<Size; i++)

        Rezult.m_array[i] = r.m_array[i] + m_array[i];

    return Rezult;

}

template <int Size>            //вычитание векторов с замещением

CVecn <Size> CVecn <Size>::operator -=(const CVecn<Size> &r) 

{   for (int i=0; i<Size; i++)

               m_array[i] -= r.m_array[i];

    return *this;

}

template <int Size>                            // вычитание векторов

CVecn <Size> CVecn <Size>::operator -(const CVecn<Size>& r)

{   CVecn <Size> Rezult;

    for (int i=0; i<Size; i++)

        Rezult.m_array[i] = r.m_array[i] - m_array[i];

    return Rezult;

}

template <int Size>                      //  скалярное произведение

double CVecn <Size>::operator *(const CVecn<Size>& r) 

{   double sum = 0;

     for (int i=0; i<Size; i++)

               sum += m_array[i] * r.m_array[i];

     return sum;

}

template <int Size>                     //  умножение вектора на скаляр

CVecn <Size> CVecn <Size>::operator *(double r)  

{   CVecn <Size> Result;

     for (int i=0; i<Size; i++)

               Result.m_array[i] = m_array[i]*r;

     return Result;

}

template <int Size>                  // логическая операция равенства векторов

bool CVecn <Size>::operator ==(const CVecn<Size> &r)

{   for (int i=0; i<Size; i++)

               if (m_array[i] != r.m_array[i])  return false;

    return true;  

}

template <int Size>               // логическая операция неравенства векторов

bool CVecn <Size>::operator !=(const CVecn<Size> &r)

{

     for (int i=0; i<Size; i++)

               if (m_array[i] != r.m_array[i])  return true;

     return false;

}

/*

template <int Size>                // можно перегрузить оператор =

CVecn<Size>& CVecn <Size>::operator =(const CVecn <Size> &r  )

{   if (&r !=this)

               for (int i=0; i<Size; i++)

                         m_array[i] = r.m_array[i];

     return *this;

}

*/

template <int Size>                                //  внешняя функция

void Print(CVecn <Size> vect)           //  вывод элементов массива на экран

{  

       for (int i=0; i<Size; i++)         cout << vect[i] << "   " ;     cout<<endl;

}

int main()

{   const SIZE=5;

                                                     // объявляем 3 объекта-вектора

     CVecn  <SIZE> vector1, vector2, vector3;

     // инициализация 1 вектора

    for (int i=0;i<SIZE;i++)  vector1[i]=i;

    cout<<" vector1=  "<<endl;       Print(vector1);

     // унарный минус

    cout<<" -vector1=  "<<endl;      Print(-vector1);

     // инициализация 2 вектора

    for (i=0;i<SIZE;i++)        vector2[i] = i + 5;

    cout<<endl<<" vector2=  "<<endl;      Print(vector2);

     // сложение двух векторов с замещением

    vector1 += vector2;

    cout<<endl<<" vector1+=vector2  "<<endl;  Print(vector1);

     // сложение двух векторов

    vector3 = vector1 + vector2;

    cout<<endl<<" vector1+vector2=  "<<endl;  Print(vector3); 

     // умножение вектора на скаляр

     vector1 = vector1 * 2;

    cout<<endl<<" vector1*=2  "<<endl;  Print(vector1);

     // умножение скаляра на вектор

    vector1=2*vector2;

    cout<<endl<<" vector2*2=  "<<endl;  Print(vector1);

     // сравнение на равенство векторов

    cout<<endl<<"vector1==vector2= "<<(vector1==vector2)<<endl;

     // скалярное произведение двух векторов

    cout<<endl<<" scalarnoe=  "<<(vector1*vector2)<<endl;  

         return 0;  

}

ПРИМЕР 16. АТД -  «комплексное число» 

Создадим АТД для комплексных чисел.

                             // файл complex.h    объявление класса

class CCmplx                                             

{

   double m_re;              // действительная часть комплексного числа

   double m_im;              // мнимая часть комплексного числа

    public:                                               

   CCmplx  (double re=0, double im=0): m_re(re), m_im(im){}  // конструктор

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

   double & Re()   {return m_re;}                 //  действ. часть

   double & Im()   {return m_im;}                //  мнимая часть

   double& operator [] (int i);                                              //   оператор []

  CCmplx& operator () (double x=0, double y=0)            //  оператор ()

                  {m_re=x; m_im=y;  return *this;}

  CCmplx& operator = (CCmplx r);                                   //  оператор =

  CCmplx& operator = (double r);                                      //  оператор =

  CCmplx operator - ();                                                       //  оператор - унарный

  CCmplx operator + ();                                                     //   оператор + унарный

  CCmplx operator ++ ();                                                   // prefix

  CCmplx operator ++ (int);                                                //postfix

  CCmplx operator +(CCmplx r);                      //    +   два комплексных  числа

  CCmplx operator - (CCmplx r);                      //   -   два комплексных  числа    

   CCmplx CCmplx::operator *(CCmplx r);      // *  два комплексных  числа

   CCmplx CCmplx::operator /(CCmplx r);       //  /  два комплексных  числа

   CCmplx operator + (double r);          //    комплексное  число + вещественное  

   CCmplx operator - (double r);           //    комплексное  число - вещественное

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

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

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