- •Ооп. Абстракция, полиморфизм, наследование, инкапсуляция
- •Методы класса: классификация методов, доступ к членам класса, неявный параметр this. Определение и реализация методов. Использование методов для экземпляров класса.
- •Перегрузка функций: правила перегрузки, выбор функции. Использование перегруженных функций.
- •Перегрузка операторов: правила перегрузки, перегрузка бинарных и унарных операторов. Использование перегруженных операторов. Понятие объектов функций (функторов).
- •Перегрузка унарных операторов
- •Бинарные операторы
- •Преобразования типа: назначение, использование. Правила преобразования типа. Возможные проблемы.
- •Оператор присваивания
- •Типы отношений между классами. Контейнерные классы: определение, видимость членов класса. Реализация и вызов конструкторов и деструкторов вложенных классов. Реализация и использование методов.
- •Вложенные классы
- •12. Понятие и назначение итераторов. Проектирование, реализация и использование итератора (на примере динамического списка).
Оператор присваивания
Оператор присваивания обязательно определяется в виде функции класса, потому что он неразрывно связан с объектом, находящимся слева от "=". Определение оператора присваивания в глобальном виде сделало бы возможным переопределение стандартного поведения оператора "=". Пример:
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 билете.
Контейнер – это способ организации хранения данных. (стек, массив, связный список….)
Контейнерные классы -- это универсальные шаблонные классы, предназначенные для хранения элементов заданного типа в смежных областях памяти. Стандарт 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.
Производные классы: простое наследование, основные понятия и определения. Правила определения производного класса, типы наследования, видимость членов класса. Реализация и использование конструкторов и деструкторов базового и производных классов. Использование экземпляров базового и производных классов. Указатели на базовый и производные классы.
Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым или родительским. Новый класс – потомком, наследником или производным классом.
Например:
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 с заданными параметрами (плохой вариант из-за высвобождения памяти в последствии)
};