|
Программирование >> Немодифицирующие последовательные алгоритмы
int main О { auto ptr<int> a(new int), b; *a.get() = 123; cout *a.get() = *a.get() endl; b = a; cout The assignment b = a has been executed.\n ; if (a.getO == NULL) cout << As a result, a.getO is NULL.\n ; cout *b.get() = *b.get() endl; return 0; Вывод этой программы следующий: *a.get() = 123 The assignment b = a has been executed. As a result, a.getO is NULL. *b.get() = 123 Поскольку выражение a.get{) является обычным указателем, значение, на которое оно указывает, обозначается как *a.get(). Преимущество использования класса auto ptr заключается в том, что память освобождается автоматически, когда уничтожается объект, принадлежащий этому классу, и это происходит только один раз: в нашем примере переменные а и 6 не содержат одновременно указатели на одну и ту же область памяти. Для прояснения механизма действия класса auto ptr посмотрим на его деструктор (в этом коде the p - скрытый (private) член класса, указывающий на размещенные данные): ~auto ptrО{delete the p;} В нашей программе деструктор вызывается как для а, так и для Ь, поэтому выполняются оба действия delete a.the p; delete b.the p; что может показаться ошибкой. Однако один из двух используемых здесь указателей равен NULL, а применение оператора delete к указателю, равному NULL, является разрешенной операцией, которая не вызывает никаких действий. Следует упомянуть об унарном операторе *, который возвращает *the p. Поскольку функция-член get возвращает указатель the p, мы упростим использованную нами запись. Например, вместо *a.get() = 123; напишем *а = 123; но должны иметь в виду, что а не является настоящим указателем. Предупреждение В отличие от прочих составляющих библиотеки STL класс auto ptr иногда критикуют за странное поведение, поэтому используйте его только тогда, когда точно знаете, что вы делаете. Например, после выполнения auto ptr<int> а(new int), b; *a.get() = 123; b = a; может показаться странным, что, хотя значение *Ь определено и равно 123, мы не имеем права использовать выражение *а, поскольку последнее присваивание приводит к обнулению указателя на целое, содержащегося в а. Причина этого заключена в необходимости освобождать память, выделенную с помощью оператора new, ровно один раз. Другае алгоритмы и контейнеры 2.1. Алгоритм accumulate Нахождение суммы элементов последовательности или подпоследовательности лучше всего достигается с помош;ью алгоритма accumulate. Этот алгоритм вместе с некоторыми другими, которые имеют отношение к вычислениям, определен в заголовке numeric, а не algorithm, как большинство остальных алгоритмов. (Если вы работаете с HP STL, то должны использовать algo.h вместо algorithm или numeric.) Следуюш;ая программа показывает, как использовать алгоритм accumulate для массива: accuml.cpp: Вычисление сумм. #include <iostream> #include <numeric> using namespace std; int mainO { const int N = 8; int a[N] = {4, 12, 3, 6, 10, 7, 8, 5}, sum = 0; sum = accumulate(a, a+N, sum); cout Sum of all elements: sum endl; cout 1000 + a[2] + a[3] + a[4] = accumulate(a+2, a+5, 1000) endl; return 0;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |