Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 12 13 14 [ 15 ] 16 17 18 ... 78


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;



1 ... 12 13 14 [ 15 ] 16 17 18 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика