6.3. Копирование вектора
6.3. Копирование вектора
Проблема
Требуется скопировать содержимое одного vector в другой.
Решение
Имеется пара способов сделать это. Можно при создании vector использовать конструктор копирования, а можно использовать метод assign. Пример 6.3 показывает оба этих способа.
Пример 6.3. Копирование содержимого vector
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// Вспомогательная функция для печати содержимого вектора
template<typename T>
void vecPrint (const vector<T>& vec) {
cout << "{";
for (typename vector<T>::const_iterator p = vec.begin();
p != vec.end(); ++p) {
cout << "{" << *p << "} ";
}
cout << "}" << endl;
}
int main() {
vector<string> vec(5);
string foo[] = {"My", "way", "or", "the", "highway"};
vec[0] = "Today";
vec[1] = "is";
vec[2] = "a";
vec[3] = "new";
vec[4] = "day";
vector<string> vec2(vec);
vecPrint(vec2);
vec.at(0) = "Tomorrow";
vec2.assign(vec.begin(), vec.end()); // Копирование каждого элемента
vecPrint(vec2); // с помощью присвоения
vec2.assign(&foo[0], &foo[5]); // Присвоение работает для всего, что
vecPrint(vec2); // ведет себя как итератор
vector<string>::iterator p;
p = find(vec.begin(), vec.end(), "new");
vec2.assign(vec.begin(), p); // Копирование подмножества полного диапазона
vecPrint(vec2); // vec
}
Обсуждение
Копирование vector просто. Имеется два способа сделать это. Можно скопировать один vector в другой с помощью конструктора копирования, как и любой другой объект, а можно использовать метод assign. О конструкторе копирования сказать почти нечего. Просто передайте в него vector, который требуется скопировать, и все.
vector<string> vec2(vec);
В этом случае vec2 будет содержать такое же число элементов, что и vec, и каждый из этих элементов будет копией элемента vec с таким же индексом. Каждый элемент копируется с помощью конструктора копирования string. Так как здесь используется конструктор, буфер vec2 имеет размер, достаточный для хранения всего, что есть в vec.
assign работает аналогично, за исключением того, что за кулисами выполняется дополнительная работа, связанная с тем, что теперь дело касается целевого vector который уже может содержать данные. Во-первых, требуется удалить элементы, которые оказались, так сказать, под ногами. Вначале assign для каждого из объектов, уже содержащихся в vec2, вызывает деструктор. После этого он проверяет размер буфера vec2, чтобы убедиться, что он достаточно большой, чтобы вместить то, что находится в vec. Если он не достаточен, assign изменяет размер буфера под размещение новых данных. Наконец, он копирует каждый элемент.
Кроме того, assign можно использовать для копирования подмножества последовательности. Например, если требуется скопировать подмножество элементов vec, просто укажите при вызове assign необходимый диапазон.
vector<string>::iterator p;
p = std::find(vec.begin(), vec.end(), "new");
vec2.assign(vec.begin(), p);
vecPrint(vec2);
В этом случае assign скопирует все до, но не включая, p. Причиной этого является соглашение, по которому во всех контейнерах и алгоритмах стандартной библиотеки assign(first, last) копирует элементы, на которые указывает first, до, но не включая, элемент, на который указывает last. Такой диапазон, который включает первый элемент, но не включает последний, часто обозначается как (first, last).
Используйте assign или конструктор копирования вместо самостоятельного циклического перебора. Это значит, не копируйте каждый элемент, перебирая vec и помещая элементы в конец vec2 в цикле. Это потребует от вас большой избыточности кода и отключит все оптимизации, которые могут присутствовать в реализации assign и конструктора копирования стандартной библиотеки.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
13.5.1. Копирование
13.5.1. Копирование Самый простой вариант создания резервной копии — использование команды cp (копирование файлов). Только в этом случае необходимо обязательно сохранять права доступа к файлу. Вот как может выглядеть команда, дублирующая директорию /home на примонтированном
8.4.1 Протоколы вектора расстояния
8.4.1 Протоколы вектора расстояния Самый простой протокол для сравнения маршрутизаторов использует счет попаданий между конечными точками пути. Некоторые улучшенные варианты оценивают стоимость или вес каждого из участков по пути следования. Например, участок попадания
Копирование
Копирование Вставьте компакт-диск в привод. Щелкните мышью на кнопке Копировать с диска (рис. 3.22). С помощью соответствующих флажков отметьте произведения, предназначенные для копирования. В строке состояния при этом будет отображаться количество выбранных
11.8. Представление динамического числового вектора
11.8. Представление динамического числового вектора ПроблемаТребуется иметь тип для манипулирования динамическими числовыми векторами.РешениеВы можете использовать шаблон valarray из заголовочного файла <valarray>. Пример 11.15 показывает, как можно использовать шаблон
11.9. Представление числового вектора фиксированного размера
11.9. Представление числового вектора фиксированного размера ПроблемаТребуется иметь эффективное представление числовых векторов фиксированного размера.РешениеВ программном обеспечении обычного типа часто более эффектный результат по сравнению с valarray дает
11.11. Вычисление нормы вектора
11.11. Вычисление нормы вектора ПроблемаТребуется найти норму (т. е. длину) числового вектора.РешениеМожно использовать функцию inner_product из заголовочного файла <numeric> для умножения вектора на самого себя, как показано в примере 11.21.Пример 11.21. Вычисление нормы вектора#include
Копирование
Копирование В этом примере мы копируем базу данных, находящуюся на диске D: удаленного сервера, в файл копии на диске F: той же самой удаленной машины. Мы направляем подробный отчет об операции в файл протокола в другом каталоге. Как обычно, пример является одной строкой:gbak
Копирование
Копирование BlindWrite Suite Сайт: http://www.blindwrite.comРазмер: 2,8 МбСтатус: SharewareЦена: $32Весьма популярная на Западе программа для точного копирования дисков. Ранее поставлялась в виде двух отдельных модулей – BlindRead, отвечавшего за сброс содержимого диска в файл-образ и собственно
1.11 Вектора
1.11 Вектора Встроенное в С++ понятие вектора было разработано так, чтобы обеспечить максимальную эффективность выполнения при минимальном расходе памяти. Оно также (особенно когда используется совместно с указателями) является весьма универсальным инструментом для
1.17 Полиморфные Вектора
1.17 Полиморфные Вектора У вас есть другая возможность – определить ваш векторный и другие вмещающие классы через указатели на объекты некоторого класса: class common (* //... *); class vector (* common** v; //... public: cvector(int); common* amp; elem(int); common* amp; operator[](int); //... *);Заметьте, что поскольку в таких
2.3.7 Указатели и Вектора
2.3.7 Указатели и Вектора Указатели и вектора в С++ связаны очень тесно. Имя вектора можно использовать как указатель на его первый элемент, поэтому пример с алфавитом можно было написать так:char alpha[] = «abcdefghijklmnopqrstuvwxyz»; char* p = alpha; char ch;while (ch = *p++) cout «„ chr(ch) „« " = " «« ch «« « = 0“ ««
5.5.5 Вектора Объектов Класса
5.5.5 Вектора Объектов Класса Чтобы описать вектор объектов класса, имеющего конструтор, этот класс должен иметь конструктор, который может вызваться без списка параметров. Нельзя использовать даже парметры по умолчанию. Например:table tblvec[10];будет ошибкой, так как для
Вектора, допускающие сложение
Вектора, допускающие сложение Приведем простой, но характерный пример, демонстрирующий необходимость введения ограниченной универсальности. Он поможет в обосновании метода решения поставленной задачи и в выборе соответствующей конструкции языка.Предположим, что мы