2013-02-15 3 views
2

Исходя из фона Java, я пытаюсь понять указатели/ссылки на C++. Я пытаюсь вернуть вектор из функции. Запись:C++ - возвращаемый вектор из функции

vector<char*> f(){ 
    vector<char*> vec; 
    return vec; 
} 

возвратит копию вектора, правильно? Лучшим способом было бы вернуть указатель на вектор:

vector<char*>* f(){ 
    vector<char*>* vec = new vector<char*>; 
    return vec; 
} 

Правильно ли это, или это совершенно неправильно?

+0

Я не говорю, что это дубликат, но этот вопрос очень хорошо обсуждает различные аспекты этой проблемы: http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c – jogojapan

ответ

0

Вы ошибаетесь, вы не хотите делать это на C++. Практически каждый C++-компилятор имеет так называемую оптимизацию с наименьшим возвратным значением, которая (эффективно) приведет к тому, что vec будет перемещен, а не скопирован, путем выделения пространства для возвращаемого значения в стеке, которое затем в основном построено «на месте», , Это устраняет накладные расходы.

Wikipedia статья об этом дает разумное изложение.

0

Я прав, или это совершенно неправильно?

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

Возврат вектора по значению в порядке. В большинстве случаев, даже в C++ 98, компилятор все равно оставил бы вызов конструктору копирования (и конструктору перемещения в C++ 11). Это называется (Named) Return Value Optimization.

В C++ 11 все контейнеры поддержки стандартной библиотеки перемещают конструкторы, поэтому даже когда копия или перемещение не отклоняются, возврат контейнера по стоимости не стоит дорого.

+0

Я говорю до 11 – Bober02

+0

Это еще не проблема, даже с кодом C++ 03. – Yuushi

1

В C++ 03 возвращение по значению, скорее всего, приводит к RVO (Оптимизация возвращаемого значения), которая будет исключать ненужную копию. В C++ 11 семантика перемещения позаботится о копии.

Итак, зачем возвращаться по значению в первую очередь? Потому что он предотвращает ненужные объекты с динамическим временем жизни. В вашем примере кода также не учитывается политика распределения, которую может использовать пользователь вашей функции.

В общем, возврат контейнера даже в C++ 11 по-прежнему представляет собой плохую идею: он ограничивает пользователей этим конкретным контейнером, так как невозможно перемещать контейнеры только для копирования. Стандартная библиотека решает эту проблему с OutputIteratorS. Ваш алгоритм, скорее всего, будет записан как:

template<typename OutputIterator> 
OutputIterator f(OutputIterator o); 

Таким образом, вы абстрактными от контейнера, а также обойти исходную задачу.

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