Я полностью согласен с Вашим утверждением, но это не имеет никакого отношения к Qt контейнерам, ни к Qt вообще. Все то же самое будет работать с std::vector или просто с любым классом (даже и не контейнером). Как объяснил Rcus такая оптимизация встроена практически во все современные компиляторы.
Это имеет прямое отношение к Qt-контейнерам. Можно сделать еще двадцать присвоений и для всех векторов будет одна копия данных.
Это легко проверяется с помощью вызова метода: vec.isDetached(), который сообщает, эксклюзивно или нет используются данные. А использует он для этого атомарную переменную ref, содержащую число объектов QVector, которые разделяю данные.
Стоит все таки заглянуть в исходники Qt.
Насчет того-же самого с std::vector...
Не умеет std::vector такого, не умеет... Поэтому, я и написал о том, что Тролли вначале поработали, а теперь могут использовать...
C++ (Qt)
#include <QApplication>
#include <QVector>
#include <vector>
#include <QDebug>
QVector<int> buildVector()
{
QVector<int> vec;
for( int i = 0; i < 100; ++i )
vec.append( i );
qDebug() << vec.constData() << vec.size();
return vec;
}
std::vector<int> buildVector_std()
{
std::vector<int> vec;
for( int i = 0; i < 100; ++i )
vec.push_back( i );
qDebug() << &vec[ 0 ] << vec.size();
return vec;
}
int main( int /*argc*/, char */*argv*/[] )
{
QVector<int> vec = buildVector();
qDebug() << vec.constData() << vec.size();
QVector<int> vec_new = vec;
qDebug() << vec_new.constData() << vec_new.size();
qDebug() << "-------------------------------------------------";
std::vector<int> vec1 = buildVector_std();
qDebug() << &vec1[ 0 ] << vec1.size();
std::vector<int> vec1_new = vec1;
qDebug() << &vec1_new[ 0 ] << vec1_new.size();
return 0;
}
0xc44fa0 100
0xc44fa0 100
0xc44fa0 100
-------------------------------------------------
0xc46cc0 100
0xc46cc0 100
0xc46ed0 100
И "увы" - мы имеем вызванный деструктор (для возвращенного объекта) + оператор присваивания, который примерно = конструктор + деструктор
А я и не говорил, что не будет вызван деструктор для локального объекта. Он вызовется, также как и оператор присваивания, только
данные копироваться не будут. Скопируется только указатель на внутренний shared-объект.
C++ (Qt)
inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(p); }
А если вызов деструктора, который не делает никаких тяжелых операций, считать большими издержками, то для чего использовать C++?
На счет такой "оптимизации" я выше уже высказался.