- •Void Print();
- •Void print()
- •Void main()
- •Void print()
- •Void main()
- •Void main()
- •Void print()
- •Void main()
- •Void print()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void print();
- •Void Drob::print()
- •Void main()
- •Void main()
- •Void print();
- •Void Drob::print()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main ()
- •Void main ()
- •Void main ()
Void main()
{
cout<<MyClass<int>::count<<endl;
cout<<MyClass<double>::count<<endl;
}
Процесс генерации компилятора , определение класса или функции по шаблону называется инстанцированием шаблона. А сгенерированные классы или функции называются специализациями. То есть специализация – это версия шаблона для конкретного типа данных. Иногда программисту необходимо написать свою специализацию явно ( например перегрузка шаблонных функций обычными).
Такая специализация называется явной.
#ifndef VECTOR_H
#define VECTOR_H
#include <iostream>
using namespace std;
typedef unsigned int uint;
template <typename T>
class Vector
{
private:
T* arr;
uint count;
public:
Vector():arr(0),count(0){}
explicit Vector(const uint initSize);
Vector(const Vector& obj);
Vector(T* array, uint arraySize);
~Vector();
uint getCount() {return count;}
bool isEmpty() {return size == 0;}
Vector& operator= (const Vector& obj);
T& operator[] (uint index);
Vector& Add(const T& item); //добавление в конец массива
Vector& Insert(const T& item, uint index); //добавление по индексу
Vector& Remove(uint index);
};
template <typename T>
Vector<T>::Vector(const uint initSize)
{
if(!initSize)
arr = 0;
else
arr = new T [initSize];
count = initSize;
}
template <typename T>
Vector<T>::Vector(const Vector& obj)
{
if(!obj.count)
arr = 0;
else
{
arr = new T [obj.count];
for(uint i=0; i<obj.count; i++)
arr[i] = obj.arr[i];
}
count = obj.count;
}
template <typename T>
Vector<T>::Vector(T* array, uint arraySize)
{
if(!arraySize)
arr = 0;
else
{
arr = new T [arraySize];
for(uint i=0; i<arraySize; i++)
arr[i] = array[i];
}
count = arraySize;
}
template <typename T>
Vector<T>::~Vector()
{
if(count)
{
delete[] arr;
arr = 0;
count = 0;
}
}
template <typename T>
Vector<T>& Vector<T>::operator= (const Vector& obj)
{
if(this == &obj) return *this;
if(!obj.count)
{
delete[] arr;
arr = 0;
}
else
{
delete[] arr;
arr = new T [obj.count];
for(uint i=0; i<obj.count; i++)
arr[i] = obj.arr[i];
}
size = obj.count;
return *this;
}
template <typename T>
T& Vector<T>::operator[] (uint index)
{
if(index >= count)
return arr[0];
else
return arr[index];
}
template <typename T>
Vector<T>& Vector<T>::Add(const T& item)
{
if(!count)
{
arr = new T;
*arr = item;
}
else
{
T* tmp = new T[count + 1];
for(uint i=0; i<count; i++)
tmp[i] = arr[i];
tmp[count] = item;
delete[] arr;
arr = tmp;
}
count++;
return *this;
}
template <typename T>
Vector<T>& Vector<T>::Insert(const T& item, uint index)
{
if(index > count) return *this;
if(!count)
{
arr = new T;
*arr = item;
}
else
{
T* tmp = new T[count + 1];
for(uint i=0; i<count; i++)
{
if(i<index)
tmp[i] = arr[i];
else
tmp[i+1] = arr[i];
}
tmp[index] = item;
delete[] arr;
arr = tmp;
}
count++;
return *this;
}
template <typename T>
Vector<T>& Vector<T>::Remove(uint index)
{
if(index >= count) return * this;
if(count == 1)
{
delete arr;
arr = 0;
}
else
{
T* tmp = new T [count-1];
for(uint i=0; i<count; i++)
{
if(i < index)
tmp[i] = arr[i];
else
tmp[i] = arr[i+1];
}
delete[] arr;
arr = tmp;
}
count--;
return *this;
}
#endif
ДИНАМИЧЕСКАЯ СТРУКТУРА ДАННЫХ
Динамическая структура – это некоторая конструкция, способная при необходимости выделять память под новые элементы или удалять выделенную память в случае необходимости во время работы программы.
СТЕК
Стек – это динамическая структура данных, представляющая из себя набор элементов в которой удаление новых элементов и удаление существующих , производится с одного конца так называемой вершины стека.
По определению элементы извлекаются из стека в порядке обратного добавления их в структуру , то есть действует принцип – последний пришел , первый ушел . (Last in First out – LIFO)
Стек не определяет нового способа хранения данных в памяти , а определяет способ доступа к ней, то есть описывает логику доступа к данным.
Основные операции над стеком.
1)Добавление элементов стека
2)Удаление элементов из стека
3)Просмотр элемента в вершине стека без удаления
4)Проверка пуст ли стек
5)Очистка стека
Очередь(First In First Out - FIFO)
Очередь содержит элементы, как бы выстроенные друг за другом цепочки.
У очереди есть начало и есть конец.
Добавлять новые элементы можно только в конец очереди, забирать элементы можно только из начала.
Принцип очереди – первый пришел , первый вышел.
Очередь, также как и стек описывает только логику доступа к данным , а не физический способ хранения информации.
ОЧЕРЕДЬ С ПРИОРИТЕТАМИ
Это очередь, в которой элементы обслуживаются в соответствии с некоторым приоритетом. Очередь с приоритетами можно реализовать в двух вариантах :
1)Очередь с приоритетным включением . Здесь последовательность элементов все время поддерживается упорядочено. То есть новые элементы добавляются на то место в последовательности, которое определяется приоритетом. А при исключении всегда выбирается элемент по значению.
2)Очередь с приоритетным исключением. Здесь новый элемент включается всегда в конец очереди , а при исключении выбирается элемент с максимальным приоритетом.
Односвязный список
Список - структура данных, которая кроме пользовательских данных хранит еще и ссылку на следующий и\или предыдущий элемент. Элементы списка могут хранится не одним блоком памяти а каждый отдельно. Указатель на следующий и\или предыдущий элемент связывает хранящий отдельно в памяти элемент списка в единую динамическую структуру. Простейшим списком является односвязный список. Элементы к такому списка хранится только указатель на следующий элемент.
value |
next |
value |
next |
value |
0 |
head |
Передвигаться по такому списку можно только в конец списка. В качестве точки входа в список используется указатель на его первый элемент называемый головой списка
Алгоритм удаления
Value |
next |
value |
next |
head |
value |
next |
value |
next |
value |
next |
head |
value |
next |
value |
next |
value |
next |
head |
value |
next |
Благодаря такой структуре списка в нем весьма эффективно осуществляется операции вставки и удаления элемента, но уменьшается скорость доступа к элементам по сравнению с массивами поскольку для этого элемент нужно найти последовательно перебирая все элементы начиная с головы списка.
Процесс построения программ
Файл.cpp Файл.cpp
Компилятор Компилятор
Файл.odj Файл.odj
1)Программист с помощью текстового редактора исходный код на языке С++.
2)Этап компиляции на этом этапе происходит преобразование кода С++ в машинный код и создается файлы с расширением .obj
3)Компоновка – на этапе происходит связывание нескольких объектов в файлы и формирование конечного .exe файла.
Раздельная компиляция
Процесс компиляции занимает довольно долго времени. Смысл раздельной компиляции, что программы можно разделять на несколько файлов и эти файлы компилируются не зависимо друг от друга, и затем связываются на этапе компоновки в один исполняемый проект. Преимущество раздельной компиляции в том, что при разделении одного файла нет необходимости пере компилировать всю программу, а только данный файл, что экономит время. Так же раздельная компиляции дает возможность нескольким программистам работать над одним проектом.
Func.cpp
#include "time.h"
using namespace std;
void func ()
{
cout<<"function"<<endl;
}
Main.cpp
#include "time.h"
#include <iostream>
using namespace std;