Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты ООП.docx
Скачиваний:
2
Добавлен:
21.04.2019
Размер:
87.01 Кб
Скачать

Оператор присваивания

Оператор присваивания обязательно определяется в виде функции класса, потому что он неразрывно связан с объектом, находящимся слева от "=". Определение оператора присваивания в глобальном виде сделало бы возможным переопределение стандартного поведения оператора "=". Пример:

class _class

{

private:

int data;

public:

_class(int i): data(i){}

_class& operator=(const _class& right) { //проверка на самоприсваивание

if (this == &right) {

return *this;

}

data = right.data; //если не равно само себе, то …

return *this;

}

};

  1. Типы отношений между классами. Контейнерные классы: определение, видимость членов класса. Реализация и вызов конструкторов и деструкторов вложенных классов. Реализация и использование методов.

//////////////////

//В шпорах написано, что всего два типа

// Спасибо поржал…

///////////////////////

В традиционном ООП предусмотрены три типа отношений между классами:

  • Использование: непосредственная зависимость.

    • член класса А отправляет сообщение объекту класса Б

///////// или

    • член класса А создает или возвращает объекты класса Б.

  • Включение: иногда называется агрегированием. Реализует логические связи типа «является составной частью».

    • объект класса А содержит внутренние объекты класса Б.

  • Наследование: реализует логические связи типа «является частным случаем».

    • ///////////////////// объясняется в 1 билете.

Контейнер – это способ организации хранения данных. (стек, массив, связный список….)

Контейнерные классы -- это универсальные шаблонные классы, предназначенные для хранения элементов заданного типа в смежных областях памяти. Стандарт C++ уже включает в себя большое количество контейнеров, как часть STL (Standard Template Library -- Стандартная Библиотека Шаблонов).

Определяется контейнер, как:

контейнер<тип> объект;

Например: vector<int> example_vector; //создаем вектор целых чисел

Вложенные классы

Один класс может быть объявлен в другом классе, в этом  случае внутренний класс называется вложенным:

class _class_1

{   class _class_2

     {      ·  ·  ·

     };

          public:

            ·  ·  ·            

};

Доступ к компонентам вложенного класса, имеющим атрибут private, возможен только из функций вложенного класса  и из функций внешнего класса, объявленных со спецификатором friend во вложенном классе.

class cls1                             //  внешний класс

{  class cls2                         //  вложенный класс

    {  int b;                            // все компоненты private для cls1 и cls2

        cls2(int bb) : b(bb){}   // конструктор класса cls2

    };

    public:                              // public секция для cls1

         int a;

    class cls3                         //  вложенный класс

    {  int c;               // private для cls1 и  cls3

      public:              // public-секция для класса cls3

        cls3(int cc): c(cc) {}   // конструктор класса cls3

    };

    cls1(int aa): a(aa) {}      // конструктор класса  cls

};                                     

void main()

{ cls1 aa(1980);               // верно

   cls1::cls2 bb(456);        // ошибка   cls2 cannot access private

   cls1::cls3 cc(789);        // верно

   cout << aa.a << endl;   // верно

   cout << cc.c << endl;   // ошибка   'c' : cannot access private member

                                  // declared in class 'cls1::cls3'

}

В приведенном тексте программы инструкция cls1::cls2 bb(456)  является ошибочной, так как объявление класса cls2 и его компонента находятся в секции private. Для устранения ошибки при описании объекта bb необходимо изменить атрибуты доступа для класса cls2 следующим образом:

public:

   class cls2

   {    int b;            // private-компонента

      public:

         cls2(int bb) : b(bb){}

   };

Пример доступа  к private-компонентам вложенного класса из функций внешнего класса, объявленных со спецификатором friend, приводится ниже.

class cls1                                         //  внешний класс

{      int a; 

   public:

       cls1(int aa): a(aa) {}

       class cls2;                                //  неполное объявление класса

       void fun(cls1::cls2);                // функция получает объект класса cls2

       class cls2                                 //  вложенный класс

       {    int c;  

         public:

            cls2(int cc) : c(cc) {}

            friend void cls1::fun(cls1::cls2);  // ф-ция, дружественная классу cls1

            int pp(){return c;}

       };

};

void cls1::fun(cls1::cls2 dd) {cout << dd.c << endl << a;}

void main()

{  cls1 aa(123);

    cls1:: cls2 cc(789);

    aa.fun(cc);

};

Внешний класс cls1 содержит public-функцию  fun(cls1::cls2 dd), где dd есть объект, соответствующий классу cls2,  вложенному в класс cls1. В свою очередь в классе cls2 имеется friend-функция   friend void cls1::fun(cls1::cls2 dd),   обеспечивающая доступ функции fun класса cls1 к локальной компоненте  с  класса cls2.

  1. Производные классы: простое наследование, основные понятия и определения. Правила определения производного класса, типы наследования, видимость членов класса. Реализация и использование конструкторов и деструкторов базового и производных классов. Использование экземпляров базового и производных классов. Указатели на базовый и производные классы.

Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым или родительским. Новый класс – потомком, наследником или производным классом.

Например:

class A{ //базовый класс

};

class B : public A{ //public наследование (public -> public, protected -> protected)

};

class C : protected A{ //protected наследование (public, protected -> protected)

};

class Z : private A{ //private наследование (public, protected -> private)

};

Данные, спрятанные в private родительского класса, не доступны из производного класса.

class A {

private:

int data;

public:

A():data(0),vasya(0){}

A(int a, int b):data(a), vasya(b)

virtual ~A() {}

int vasya;

};

class B:public A {

private

int aa;

public:

B(int a, int b):aa(a), vasya(b)

~B(){}

func() {

int a;

a = data; //ошибка доступа (data была в private родительского класса)

a = vasya; // все ок (vasya был в public родительского класса)

};

};

int main() {

A* aaa = new A; // создание экземпляра класса А(пустой конструктор)

A* aaa_2 = new A(23,42) // создание экземпляра А с заданными параметрами

B* bbb_2 = new B(23, 52) // создание экземпляра B с заданными параметрами (лучше использовать данный вариант)

A* bbb = new B(23, 52) // создание экземпляра B с заданными параметрами (плохой вариант из-за высвобождения памяти в последствии)

};