Download presentation
Presentation is loading. Please wait.
1
ООП Классы
2
Данные отдельно, методы отдельно struct Node { Node* next; void* data; }; struct List { Node* first; int size; }; void* allocate() { … } void add (void* cont, void* data) { … } int size (void* cont) { … } void* remove (void* cont, int pos) { … } void release(void* cont) { … } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = (List*)allocate(); add(list, a+1); add(list, a+5); remove(list,1); printf(“Size: %d”, size(list)); release(list); }
3
Проблема №1: подаем некорректные данные void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; void* bbb = NULL; List* list = (List*)allocate(); add(bbb, a+1); add(a, a+5); remove(a,1); printf(“Size: %d”, size(bbb)); release(list); }
4
Данные и методы вместе (объект) struct Node { Node* next; void* data; }; void* allocate() { … } void release(void* cont) { … } struct List { Node* first; int size; void add (void* data) { … } int size () { … } void* remove (int pos) { … } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = (List*)allocate(); list->add(a+1); list->add(a+5); list->remove(1); printf(“Size: %d”, list->size()); release(list); }
5
Проблема №2: не защищено создание и удаление void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; void* bbb = NULL; List* list = (int*)allocate(); list->add(a+1); list->add(a+5); list->remove(1); printf(“Size: %d”, list->size()); release(bbb); } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; void* bbb = NULL; List list = ??? // мы знаем только как создавать указатель на структуру List }
6
Не получается void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; void* bbb = NULL; List* list = ???->allocate(); list->add(a+1); list->add(a+5); list->remove(1); printf(“Size: %d”, list->size()); list->release(); free(list); // две операции } struct List { Node* first; int size; void add (void* data) { … } List* allocate() { … } List allocate2() { … } void release() { … }
7
Конструктор и деструктор struct Node { Node* next; void* data; }; struct List { Node* first; int size; List() { … } // конструктор void add (void* data) { … } int size () { … } void* remove (int pos) { … } ~List() { …} // деструктор } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = new List(); list->add(a+1); list->add(a+5); list->remove(1); printf(“Size: %d”, list->size()); delete list; // ~List() } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List list(); list.add(a+1); list.add(a+5); list.remove(1); printf(“Size: %d”, list.size()); } // после завершения функции выполнится деструктор ~List()
8
Бонус: несколько конструкторов struct Node { Node* next; void* data; }; struct List { Node* first; int size; List() { … } //создать пустой список List(int* array, int array_size) { … } // создать список и заполнить его данными из массива } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = new List (a, 10); printf(“Size: %d”, list->size()); // 10 delete list; // ~List() } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List list(a, 10); printf(“Size: %d”, list.size()); // 10 } // после завершения функции выполнится деструктор ~List()
9
Проблема №3: портим состояние объекта void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = new List(); list->add(a+1); list->add(a+5); list->remove(1); list->first = NULL; // не освободили память предварительно list->size = 1000; // некорректный размер printf(“Size: %d”, list->size()); // покажет: 1000 delete list; // ~List() }
10
Защищаем доступ. Инкапсуляция. struct Node { Node* next; void* data; }; class List { private: Node* first; int size; public: List() { … } // конструктор void add (void* data) { touch(); // no problem … } int size () { return size; // no problem } void* remove (int pos) { touch(); … } ~List() { …} // деструктор private: void touch() { // запоминаем время } void main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; List* list = new List(); list->add(a+1); list->add(a+5); list->remove(1); list->first = NULL; // ошибка компиляции list->size = 1000; // ошибка компиляции printf(“Size: %d”, list->size()); list->touch(); // ошибка компиляции delete list; // ~List() }
11
Проблема №4: защита вспомогательной структуры class Node { private: Node* next; void* data; }; class List { private: Node* first; int size; public: List() { … } // конструктор void add (void* data) { touch(); // no problem Node newNode = new Node(); newNode->next = NULL; // ошибка компиляции newNode->data = data; // ошибка компиляции … } int size () { return size; // no problem } … } Кто-то может воспользоваться нашей структурой случайно (в своем коде): void main() { Node n* = new Node(); // no problem }
12
Друзья класса class List; // нужно указать, что класс такой есть class Node { friend List; private: Node* next; void* data; Node() { … }; }; class List { private: Node* first; int size; public: List() { … } // конструктор void add (void* data) { touch(); // no problem Node newNode = new Node(); newNode->next = NULL; // no problem newNode->data = data; // no problem … } … } Кто-то может воспользоваться нашей структурой случайно (в своем коде): void main() { Node n* = new Node(); // ошибка компиляции, конструктор приватный ! }
13
Соглашение: разделение интерфейса и реализации Файл List.hpp class List; class Node { friend List; private: Node* next; void* data; Node(); }; class List { private: Node* first; int size; public: List(); // конструктор void add (void* data); int size () { return size;// можно оставить } void* remove (int pos) ; ~List(); // деструктор private: void touch() ; } Файл List.cpp #include “List.hpp” Node::Node() { … } List::List() { // конструктор … } void List::add (void* data) { … } void* List::remove (int pos) { … } List::~List() { … } List::touch(){ … }
14
Бонус: переопределение операций class Complex { private: float myReal; float myImag; public: Complex(float re, float im) { myReal = re; myImag = im; } Complex operator+(Complex c) { Complex sum(myReal+c.myReal, myImag+c.myImag); return sum; } Complex operator+(double re) { Complex sum(myReal+re, myImag); return sum; } Complex operator+(int re) { Complex sum(myReal+re, myImag); return sum; } void print() { printf("Complex: %f %f\n", myReal, myImag); } float& operator[] (int pos) { if (pos ==0) return myReal; else return myImag; } }; // end of class definition // внещний оператор Complex operator+(double d, Complex c2) { Complex sum(d+c2.Real(), c2.Imag()); return sum; }
15
Бонус: переопределение операций void main() { Complex c1 (1.1, 0); Complex c2 (9,9.9); int i = 0; double d = 0.0; Complex c = c1 + c2; // Вызов: Complex operator+(Complex c) {…} c = c1 + i; // Вызов: Complex operator+(int re) {…} c = c1 + d; // Вызов: Complex operator+(double re) {…} c = d + с1; // Вызов: Complex operator+(double d, Complex c2) {…} c[0] = 1; // Вызов: float& operator[] (int pos) {…} c[1] = 8; // Вызов: float& operator[] (int pos) {…} c.print(); }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.