|
Программирование >> Инициализация объектов класса, структура
class Account { public: ... static Account* init heap array( vector<value pair> &init values, vector<value pair>::size type elem count = 0 ); static void dealloc heap array( Account*, size t ); ... typedef pair<char*, double> value pair; 14.4.2. Вектор объектов Когда определяется вектор из пяти объектов класса, например: vector< Point > vec ( 5 ); то инициализация элементов производится в следующем порядке5: 1. С помощью конструктора по умолчанию создается временный объект типа класса, хранящегося в векторе. . 2. К каждому элементу вектора применяется копирующий конструктор, в результате чего каждый объект инициализируется копией временного объекта. 3. Временный объект уничтожается. Хотя конечный результат оказывается таким же, как при определении массива из пяти объектов класса: Point pa[ 5 ]; эффективность подобной инициализации вектора ниже, так как, во-первых, на конструирование и уничтожение временного объекта, естественно, нужн: ресурсы, а во-вторых, копирующий конструктор обычно оказывается вычислительно более сложным, чем конструктор по умолчанию. Общее правило проектирования таково: вектор объектов класса удобнее только для вставки элементов, т.е. в случае, когда изначально определяется пустой вектор. Если мы заранее вычислили, сколько придется вставлять элементов, или имеем на этот счет обоснованное предположение, то надо зарезервировать необходимую память, а затем приступать к вставке. Например: 5 Сигнатура ассоциированного конструктора имеет следующий смысл. Копирующий конструктор применяет некоторое значение к каждому элементу по очереди. Задавая в качестве второго аргумента объект класса, мы делаем создание временного объекта излишним: i explicit vector( size type n, const T& value=T(), const Allocator&=Allocator()); арифметические операции над указателями приходится программировать самостоятельно. М1 объявляем обе функции статическими членами класса: vector< Point > cvs; пустой int cv cnt = calc control vertices(); зарезервировать память для хранения cv cnt объектов класса Point cvs все еще пуст . cvs.reserve( cv cnt ); открыть файл и подготовиться к чтению из него ifstream infile( spriteModel ); istream iterator<Point> cvfile( infile ),eos; вот теперь можно вставлять элементы copy( cvfile, eos, inserter( cvs, cvs.begin() )); (Алгоритм copy() , итератор вставки inserter и потоковый итератор чтения istream iterator рассматривались в главе 12.) Поведение объектов list (список) и deque (двусторонняя очередь) аналогично поведению объектов vector (векторов). Вставка объекта в любой из этих контейнеров осуществляется с помощью копирующего конструктора. Упражнение 14.9 Какие из приведенных инструкций неверно:? Исправьте их. (b) Account iA[1024] = { Nhi , Le , Jon , Mike , Greg , Brent , Hank (a) Account *parray[10] = new Account[10]; Roy , Elena }; (d) string as[] = *pe; (c) string *ps=string[5]( Tina , Tim , Chyuan , Mira , Mike ); Упражнение 14.10 Что лучше применить в каждой из следующих ситуаций: статический массив (такой, как Account pA[10]), динамический массив или вектор? Объясните свой выбор. Внутри функции Lut() нужен набор из 256 элементов для хранения объектов класса Color. Значения являются константами. Необходимо хранить набор из неизвестного числа объектов класса Account. Данные счетов читаются из файла. Функция gen words (elem size) должна сгенерировать и передать обработчику текста набор из elem size строк. Упражнение 14.11 печально: не проверяется, что parray адресует массив неверная запись delete parray; правильно: определяется размер массива, адресуемого parray вместо delete [] parray; Наличие пары скобок заставляет компилятор найти размер массива. Затем к каждому элементу по очереди применяется деструктор (всего size раз). Если же скобок нет, уничтожается только один элемент. В любом случае освобождается вся память, занятая массивом. При обсуждении первоначального варианта языка С++ много спорили о том, должно ли наличие квадратных скобок инициировать поиск или же (как было в исходной в первоначальном варианте яза размер массива требовалось задавать явно спецификации) лучше поручить программисту явно указывать размер массива: delete p[10] parray; Как вы думаете, почему язык был изменен таким образом, что явного задания размера не требуется (а значит, нужно уметь его сохранять и извлекать), но скобки, хотя и пустые, в операторе delete остались (так что компилятор не должен запоминать, адресует указатель единственный объект или массив)? Какой вариант языка предложили бы вы? 14.5. Список инициализации членов #include <string> class Account { public: ... private: unsigned int acct nmbr; double balance; string name; Модифицируем наш класс Account, объявив член name типа string: Потенциальным источником ошибок при использовании динамических массивов является пропуск пары квадратных скобок, говорящей, что указатель адресует массив, т. е.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |