Presentation is loading. Please wait.

Presentation is loading. Please wait.

ООП Классы. Данные отдельно, методы отдельно struct Node { Node* next; void* data; }; struct List { Node* first; int size; }; void* allocate() { … } void.

Similar presentations


Presentation on theme: "ООП Классы. Данные отдельно, методы отдельно struct Node { Node* next; void* data; }; struct List { Node* first; int size; }; void* allocate() { … } void."— Presentation transcript:

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(); }


Download ppt "ООП Классы. Данные отдельно, методы отдельно struct Node { Node* next; void* data; }; struct List { Node* first; int size; }; void* allocate() { … } void."

Similar presentations


Ads by Google