Подтвердить что ты не робот

В чем смысл "общего программирования" в С++?

В чем смысл общего программирования в С++?

Кроме того, я пытаюсь выяснить, что означает контейнер, iterator и разные типы.

4b9b3361

Ответ 1

Общее программирование означает, что вы не пишете исходный код, который компилируется как есть, но вы пишете "шаблоны" исходных кодов, которые компилятор в процессе компиляции преобразуется в исходные коды. Простейшим примером для общего программирования являются классы контейнеров, такие как массивы, списки или карты, содержащие коллекцию других объектов. Но есть еще много общего для программирования. В контексте С++ (и называется мета-программирование) это означает, что программы, которые оцениваются во время компиляции, записываются.

Основным примером универсального программирования являются шаблоны контейнеров: на статически типизированном языке, таком как С++, вам придется объявлять отдельные контейнеры, содержащие целые числа, поплавки и другие типы, или иметь дело с указателями на void и, следовательно, потерять все типы Информация. Шаблоны, которые являются способом общего программирования на С++, используют это ограничение, позволяя вам определять классы, когда один или несколько параметров не определены в момент определения класса. Когда вы экземпляр шаблона позже, вы сообщите компилятору, который он должен использовать, чтобы создать класс из шаблона. Пример:

template<typename T>
class MyContainer
{
    // Container that deals with an arbitrary type T
};

void main() 
{
    // Make MyContainer take just ints.
    MyContainer<int> intContainer;
}

Шаблоны generic, потому что компилятор переводит шаблон в фактический код. Обратите внимание, что в случае, если вы не создаете экземпляр своего шаблона, для него не будет создан код. С другой стороны, если вы объявите MyContainer<int>, a MyContainer<float> и a MyContainer<String>, то компилятор будет создавать три версии вашего кода, каждый из которых имеет другой тип. Будут задействованы некоторые оптимизации, но в основном ваш шаблон кода будет обновлен тремя новыми типами.

Итераторы - это шаблон дизайна, который был популяризирован в оригинальной книге "Шаблоны проектирования" Gamma et al. Это шаблон для перебора содержимого класса контейнера. В отличие от использования for -loop, итератор представляет собой экземпляр класса, который указывает на член контейнера и дает вам единый интерфейс для перемещения контейнера, а также доступа к членам. Взгляните на этот пример:

// Instanciate template QList with type int
QList<int> myList;

// put some ints into myList

// Copyconstruct iterator that points to the
// first member of the list.
QList<int>::iterator i = myList.begin();

// Iterate through the list 
while (i != myList.end()) {
  std::cout << *i << std::endl;
  i++;
}

В этом примере на С++ я создаю шаблон QList с типом int. QList контейнер класс, который хранит список объектов. В этом примере мы будем использовать его для хранения целых чисел.

Затем я создаю iterator i для прохождения по списку. myList.begin() возвращает итератор, который указывает на первый элемент списка. Мы можем сравнить итератор с другим итератором myList.end(), который указывает после последнего элемента списка. Если оба итератора одинаковы, мы знаем, что мы прошли последний экзамен. В цикле мы печатаем элемент, обращаясь к нему с помощью *i и переходим к следующему элементу с помощью i++.

Обратите внимание, что в этом примере * и ++ являются перегруженными операторами и переопределены классом итератора. На языке программирования без перегрузки оператора могут быть такие методы, как i.element() или i.next(), которые выполняют одну и ту же задачу. Важно заметить, что i не является указателем, а целым классом, который просто имитирует поведение указателя.

Какая польза от итераторов? Они обеспечивают единый способ доступа к членам класса контейнера, полностью зависящим от того, как класс контейнера реализован внутри. Независимо от того, хотите ли вы перемещаться по списку, карте или дереву, классы итератора (должны) всегда работают одинаково.

Ответ 2

Container

В С++ контейнер - это класс, который позволяет хранить объекты. Например, стандартная библиотека std::vector<T> представляет собой изменяемый размер массива, который хранит объекты некоторого типа T. Чтобы формально считаться классом контейнера, он должен выставлять определенные функции для облегчения общего программирования. Я мог бы привести конкретные требования к стандарту С++, но для большинства целей соответствующие классы контейнеров являются таковыми из стандартной библиотеки: vector, deque, list, map, set и multimap/multiset.

Одним из важных требований является то, что они должны разрешать доступ к итератору.

Итератор

"Итератор" может означать две вещи здесь: это имя шаблона проектирования, но в С++ это также имя конкретного выражения этого шаблона проектирования. Итератор С++ - это тип, который позволяет обходить последовательность элементов, используя синтаксис, подобный указателю.

Например, если у вас есть массив int a[10], вы можете использовать простой указатель как итератор:

int* first = a; // create an iterator that points to the beginning of the array
++first; // make the iterator point to the second element
int i = *first; // get the value of the element pointed to by the iterator
int* last = a+10; //create an "end" iterator, one which points one past the end of the array

Если бы у меня был связанный список, например std::list<int> l, я мог бы сделать то же самое, хотя теперь мои итераторы уже не просто указатели, а вместо этого тип класса, реализованный специально для работы с std::list:

std::list<int>::iterator first = l.begin(); // create an iterator that points to the beginning of the list
++first; // make the iterator point to the second element
int i = *first; // get the value of the element pointed to by the iterator
std::list<int>::iterator last = l.end(); //create an "end" iterator, one which points one past the end of the list

или с вектором std::vector<int> v:

std::vector<int>::iterator first = v.begin(); // create an iterator that points to the beginning of the vector
++first; // make the iterator point to the second element
int i = *first; // get the value of the element pointed to by the iterator
std::list<int>::iterator last = v.end(); //create an "end" iterator, one which points one past the end of the vector

Важная информация об итераторах заключается в том, что они дают нам единый синтаксис для прохождения последовательностей элементов, независимо от того, как последовательность хранится в памяти (или даже если она хранится в памяти. Итератор может быть записан для итерации по содержимое базы данных на диске. Или мы можем использовать обертки итератора, чтобы поток, такой как std::cin, также выглядел как последовательность объектов:

std::istream_iterator<int>(std::cin) first;
    ++first; // make the iterator point to the second element
    int i = *first; // get the value of the element pointed to by the iterator
    std::list<int>::iterator last; //create an "end" iterator, which marks the end of the stream

хотя из-за того, что это обертывает регулярный поток, это более ограниченный тип итератора (вы не можете двигаться назад, например, что означает, что не все из следующих алгоритмов работают с итераторами потоков.

Теперь, учитывая любой из этих типов итераторов, мы можем использовать все стандартные библиотечные алгоритмы, которые предназначены для работы с итераторами. Например, чтобы найти первый элемент в последовательности со значением 4:

std::find(first, last, 4); // return the first iterator which equals 4 and which is located in the interval [first, last)

Или мы можем сортировать последовательность (не работает с итераторами потоков):

std::sort(first, last);

или если мы напишем функцию, которая квадратизирует int, например:

int square(int i) { return i * i; }

то мы можем применить его ко всей последовательности:

// for every element in the range [first, last), apply the square function, and output the result into the sequence starting with first
std::transform(first, last, first, square);

Это преимущество итераторов: они абстрагируют детали контейнера, поэтому мы можем применять общие операции для любой последовательности. Благодаря итераторам такая же реализация find или sort работает со связанными списками, а также с массивами или даже с вашими собственными классами контейнеров для дома.

Общее программирование

Общее программирование - это в основном идея о том, что ваш код должен быть как можно более общим. Как показано в приведенных выше примерах итератора, мы предлагаем общий набор функций, которые тип должен поддерживать для того, чтобы быть названным итератором, а затем мы пишем алгоритмы, которые работают с любым типом итератора.

Сравните это с традиционным объектно-ориентированным программированием, где итераторы должны "доказать", что они являются итераторами, наследуя от какого-то интерфейса IIterator. Это помешало бы нам использовать исходные указатели в качестве итераторов, поэтому мы потеряли бы природу.

В С++ с общим программированием нам не нужен официальный интерфейс. Мы просто пишем алгоритмы с использованием шаблонов, поэтому они принимают любой тип, который так выглядит, как итератор, независимо от того, где, когда и как они определены, и независимо от того, происходят они из общего базового класса или интерфейса.

Ответ 3

В простейшем определении, общее программирование - это стиль компьютерного программирования, в котором алгоритмы записываются в терминах типов, подлежащих заданию-позже, которые затем создаются при необходимости для определенных типов, предоставляемых в качестве параметров.

Ответ 4

В качестве точки, представляющей исторический интерес, версии С++, которые приходили перед шаблонами, были частью языка, имеющего " generic.h", который содержащиеся макросы препроцессора, которые могут быть расширены для объявлений классов. Таким образом, у вас может быть общая схема ( "шаблон" ) для класса, который вы можете изменить, передав определенные параметры в макросы, когда вы расширили их до фактических деклараций классов. Однако макросы препроцессора не являются безопасными по типу и немного неуклюжими для обработки, и их использование в коде на С++ значительно уменьшилось из-за этих причин; С++ принял более универсальные шаблоны в качестве элементов языка, но термин "общее" программирование продолжался. "Дженерики" теперь используются на других языках программирования в качестве прославленных типов. Помимо этого, этот вопрос уже получил квалифицированный ответ.

Ответ 5

общее программирование: в значительной степени просто используются шаблоны.

container: структура или класс, который содержит свои собственные данные и методы, которые действуют на эти данные.

Итератор: это указатель на некоторый адрес памяти, через который вы можете перебирать (например, массив).

Исправьте меня, если не ошибаетесь ни на одном из вышеперечисленных.

Ответ 6

понятие параметров типа, которые позволяют создавать классы и методы, которые откладывают спецификацию одного или нескольких типов до тех пор, пока класс или метод не будут объявлены и не будут созданы кодом клиента.