Главная Обратная связь Дисциплины:
Архитектура (936)
|
Операция получения адреса самого указателя
Пример: char *point_Ch; printf("Адрес переменной point_Ch = %08X\n",&point_Ch);
Организация списка объектов различного типа. Техническая реализация Виртуальных функций. Виртуальный метод (виртуальная функция) — в объектно-ориентированном программировании метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения. Таким образом, программисту необязательно знать точный тип объекта для работы с ним через виртуальные методы: достаточно лишь знать, что объект принадлежит классу или наследнику класса, в котором метод объявлен. Виртуальные методы — один из важнейших приёмов реализации полиморфизма. Они позволяют создавать общий код, который может работать как с объектами базового класса, так и с объектами любого его класса-наследника. При этом базовый класс определяет способ работы с объектами и любые его наследники могут предоставлять конкретную реализацию этого способа. Если в родительском классе некоторая функция объявлена как виртуальная, то в производном классе ее можно переопределить. В этом, собственно говоря, ничего нового нет – этомы могли делать и без всяких виртуальных функций. Новое заключается в том, что если мы запишем в переменную типа родительского класса экземпляр проиводного, то для такого экземпляра мы сможем вызывать переопределенную функцию производного класса. Вот пример, поясняющий это: { class Worker { protected int age=0; virtual public void setAge(int age) { if(age>0 && age<100) this.age=age; else this.age=0; } public int getAge() { return age; } } //Класс Boss class Boss : Worker { public int numOfWorkers; //Количество подчиненных override public void setAge(int age) { if(age>0 && age<45) this.age=age; else this.age=0;} } class Test { static void Main(string[] args) { Worker boss = new Boss(); boss.setAge(50); Console.WriteLine("Возраст босса "+boss.getAge()); } }} Как вы видите, тут функцию setAge в родительском классе Worker мы определили с ключевым словом virtual, а одноименную функцию в производном классе Boss – с ключевым словом ovеrride. Обратите внимание на то, что из какого конкретно класса вызывается функция (из родительского или производного) определяется на этапе выполнения программы, а не на этапе компиляции. В принципе в переменную родительского типа мы могли бы записать экземпляр именно родительского класса. Для организации списка каких-либо объектов мы используем шаблоны. например template <class T> class SpisokChegoLibo; template <class Type> class SpisokChegoLibo { public: SpisokChegoLibo() ;//конструктор ~SpisokChegoLibo();//деструктор private: T data; SpisokChegoLibo<Type> *front; SpisokChegoLibo<Type> *back; //в зависмости от того какой именно список мы создаем. }; В зависимости от случая поля могут изменяться.
Параметризованная очередь. Параметризованный стек. Параметризованное бинарное дерево. По аналогии с параметризованной функцией можно построить параметризованное описание класса, позволяющее создавать экземпляры классов для конкретных значений параметров. Параметризованный класс описывается следующим образом: template <class T > class описание класса Как и для функций, в описателе template может быть задано несколько параметров. В самом описание класса имена параметров используются как имена типов данных, типов параметров функций и типов значений, возвращаемых функциями. В качестве примера приведем описание класса stack, предназначенного для построения стеков фиксированного максимального размера с элементами произволного типа. Enum BOOLEAN ( FALSE, TRUE ); template <class Type > Class stack { private: enum ( EMPTY = -1 ); Type* s; /* Указатель на массив стека */ int max_len; /* Максимальная длина стека */ int top; /* Индекс элемента в вершине стека */ public: stack ( ) : max_len ( 100 ) /* конструктор без параметров */ { s = new Type [ 100 ]; top = EMPTY; } stack ( int size ) : max_len( size ) /* Второй конструктор */ { s = new Type [ size ]; top = EMPTY; } ~stack ( ) { delete [ ] s; } /* Деструктор */ void reset ( ) { top = EMPTY; } /* Очистить стек */ void push ( Type c ) { s [ ++top ] = c; } Type pop ( ) { return (s [top—] } Type top_of ( ) { return ( s [top ] } BOOLEAN empty ( ) { return BOOLEAN ( top == EMPTY ) } BOOLEAN full ( ) { return BOOLEAN ( top == max_len ) } }; Следует отметить, что в этом примере с целью сокращения исходного текста не предусмотрен контроль выхода за пределы стека в методах push и pop. Чтобы создать экземпляр параметризованного объектного типа, нужно уточнить имя типа значением параметра в угловых скобках:
Бинарное дерево_биинарным деревом называется конечное множетсво узлов,которое или пусто, или состоит из корня и двух непересакающихся бинарных деревьев,называющихся левым и правым поддеревьями данного дерева. template<class DataT> class tree { DataT info; tree *llink;//ссылка на «левую» ветвь tree *rlink;//ссылка на «правую» ветвь public: tree *root; // корень дерева tree(){root=NULL;}; // конструктор void in(tree<DataT> *&t); // ввод дерева void btree1(tree<DataT> *t); void btree2(tree<DataT> *t); void btree3(tree<DataT>*t); далее также реализуем ввод дерева,и обход, в обратном,концевом и прямых порядках. Обход в прямом порядке – попасть в корень, пройти левое поддерево в прямом порядке.пройти правое поддерево в прямом порядке. Обход в обратном порядке: пройти левое поддерево в обратном порядке, попасть в корень , и пройти правое поддерево в обратном порядке. Обход в концевом порядке- пройти левое поддерево в концевом порядке, пройти правое поддерево в концевом порядке, попасть в корень. Обходы бинарного дерева с рисунка. 1)в прямом порядке ABDCEGFHJ 2)в обратном DBAGECHFJ 3)в концевом DBGEHJFCA
Очередь – абстрактная структура данных, реализует принцип обслуживания FIFO. Это частный случай однонаправленного списка, добавление элементов в который выполняется в один конец, а выборка идет из другого конца. Таким образом, в структуре «очередь» определены две операции: добавление элементов и выборка. При выборке элемент из очереди исключается. В системном программировании очереди используются для диспетчеризации задач моделирования. «первым пришел,первым ушел» Необходимо, чтобы наш класс Queue поддерживал следующие операции: 1. добавить элемент в конец очереди: void add( item ); 2. удалить элемент из начала очереди: item remove(); 3. определить, пуста ли очередь: bool is_empty(); 4. определить, заполнена ли очередь: bool is_full(); // объявление QueueItem template <class T> class QueueItem; template <class Type> class Queue { public: Queue() : front( 0 ), back ( 0 ) { } ~Queue(); Type& remove(); void add( const Type & ); bool is_empty() const { return front == 0; } private: QueueItem<Type> *front; QueueItem<Type> *back; }; #endif
|