2013-03-02 3 views
3

Предположим, у меня есть большой многоуровневый вектор. (Это просто пример для нескольких уровней содержащегося в ней объект дерева)Как эффективно работать с контейнером C++?

vector<vector<vector<int>>> vec1 = getBigVector(); 

Если мне нужно передать элемент, я думаю, что это приведет к своему роду копирование.

vector<vector<int>> vec2 = vec1[2]; 
vector<vector<int>> vec3 = vec1[3]; 

Не выглядит действительно эффективным, чем ссылка. Насколько я знаю, C++ обычно выбирается для его эффективности, и я слышал, что C++ предназначен для предпочтения объекта типа значения. Но верно ли это для контейнеров со многими элементами? Как насчет контейнера содержит другие контейнеры?

Есть ли скрытый секрет, который может сделать операцию эффективной? Или я должен просто ссылаться на него вместо копирования?

Update

Всего дерева объектов нуждается в частой мутации. И даже само дерево должно быть мутировано.

+1

умные указатели возможно? –

+3

Если вам не нужна модифицируемая копия этого элемента, ссылка на const будет, вероятно, вам интересно о производительности. Честно говоря, если эти векторы получат даже умеренно респектабельные размеры, вы были бы сумасшедшими * not * to. – WhozCraig

+0

Если вам просто нужна ссылка на элементы в большом векторе, тогда сделайте именно это - используйте ссылку на элементы. Если вы хотите поместить элементы в другое место, у вас есть три варианта: вы можете скопировать элементы в новое место, вы можете переместить элементы в новое место или изменить свой дизайн, чтобы большой вектор содержал ' shared_ptr 'и делиться элементами между большим вектором и новым местоположением. – Mankarse

ответ

3

В общем, да, используйте ссылки вместо копий. Если вы не хотите, чтобы нуждался в, чтобы скопировать весь объект (если ссылка сделана так же хорошо), используйте ссылку.

Однако иногда вы просто хотите переместить или переименовать существующий объект. В этом случае вы можете использовать функцию std::move (нова в C++ 11), которая в основном сообщает STL, что это нормально, если вы стареете старый объект, если это помогает быстрее создать новый.

Примеры:

vector<vector<int>> vec2 = vec1[2]; 

означает "создать совершенно новый объект, так что теперь есть два объекта." Это очень медленно.

vector<vector<int>> &vec2 = vec1[2]; 

означает «все еще существует только один объект, но теперь есть две ссылки на него». Это самый быстрый вариант.

vector<vector<int>> vec2 = std::move(vec1[2]); // C++11 

означает «есть два объекта, но vec2 украл внутренностей из vec1[2], так vec1[2] просто пустая шелуха.» Это, как правило, довольно быстрая операция, хотя и не так быстро, как просто создание ссылки, конечно. Ошибочно пытаться что-либо сделать с vec1[2] после того, как это было std::move d out; единственное, что вы можете сделать на законных основаниях, это назвать его деструктором.

Дополнительную информацию о C++ 11's std::move, Google "rvalue references".

Смежные вопросы