Время жизни элементов vector :: push_back () - PullRequest
2 голосов
/ 14 августа 2011

Я хочу подтвердить то, что, как мне кажется, я понимаю о времени жизни объектов, которые были push_back() 'обработаны на std::vector. То, что я прочитал, говорит о том, что элементы вектора являются копиями. Таким образом, использование ниже ОК? В частности, является ли переменная s в f2() экземпляром std::string, отличным от того, который push_back() 'имеет значение в f1(), и поэтому безопасна для использования?

void f1(std::vector<std::string>* pv) {
    std::string s = "hi";               
    pv->push_back(s);
}

void f2(void) {
    std::vector<std::string> v;
    f1(&v);
    for (size_t i = 0; i < v.size(); ++i) {
        std::string s = v.at(i);
        std::cout << s;
    }
}

Ответы [ 4 ]

4 голосов
/ 14 августа 2011

Да, это правильно.Копия строки s сохраняется во время push_back.Проверьте документация для деталей.В нем говорится:

void push_back ( const T& x );

Добавляет новый элемент в конце вектора, после его текущего последнего элемента. Содержимое этого нового элемента инициализируется в виде копии x.

Параметры
x
Значение для копированияновый элемент .
T - это первый параметр шаблона (тип элементов, хранящихся в векторе).

3 голосов
/ 14 августа 2011
std::string s = "hi";               
pv->push_back(s);

Обратите внимание, что это излишне неэффективно. Поскольку s является lvalue, push_back действительно сделает копию. Если вместо этого вы скажете pv->push_back(std::string("hi")), компилятор C ++ 0x может заменить копию на move , потому что std::string("hi") - это значение. Можно даже сказать:

pv->emplace_back("hi");

для создания строкового объекта на месте. Копирование или перемещение не требуется.

1 голос
/ 14 августа 2011

При выполнении операции push_back, описанной выше, она создает копию строки s. Так что это безопасно.

0 голосов
/ 14 августа 2011

Да, это правильно.Строка s будет скопирована.

Однако есть одна интересная вещь о том, как обычно реализуется строка класса, которую стоит упомянуть.Если вы создаете новую строку из другой строки или из указателя const char, он сначала не копирует все символы в свой внутренний массив, но использует указатель на исходные данные.Только когда вы хотите изменить строку (или изменилась исходная строка), создается фактическая копия массива символов.Таким образом, строковые экземпляры эффективно совместно используют символьные данные, если они не изменены.

В случае вашего кода нажатие s скопирует экземпляр строки, но не скопирует символы «привет», поэтому это будетбыть относительно быстрым.

РЕДАКТИРОВАТЬ:

, как отмечали другие, в настоящее время оптимизация копирования при записи больше не распространена, поэтому не обращайте внимания;) здесь некоторая информация, почемуэто дело

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...