Ответ 1
Поведение, которое вы наблюдаете, связано с порядком вызовов, сделанных в QVector::begin
и QVector::cbegin
. Если вызов первого происходит до вызова последнего, то их возвращаемые значения сравниваются равными, но если вы отменяете порядок, они не сравниваются с равными. Это может быть продемонстрировано с помощью следующего кода:
QVector<int> c;
std::cout << static_cast<void const *>(c.begin()) << std::endl;
std::cout << static_cast<void const *>(c.cbegin()) << std::endl;
Отпечатанные адреса будут одинаковыми. Однако, если вы поменяете порядок двух операторов печати, адреса будут разными.
Если вы вникнете в исходный код для двух функций-членов, вы увидите
inline iterator begin() { detach(); return d->begin(); }
inline const_iterator cbegin() const { return d->constBegin(); }
И прослеживая назад, тела как d->begin()
, так и d->constBegin()
идентичны. Поэтому разница в вызове QVector::detach()
в первом случае. Это определяется как
template <typename T>
void QVector<T>::detach()
{
if (!isDetached()) {
#if QT_SUPPORTS(UNSHARABLE_CONTAINERS)
if (!d->alloc)
d = Data::unsharableEmpty();
else
#endif
reallocData(d->size, int(d->alloc));
}
Q_ASSERT(isDetached());
}
Объяснение того, что происходит, можно найти здесь.
Контейнеры Qts неявно разделяются - при копировании объекта копируется только указатель на данные. Когда объект изменен, он сначала создает глубокую копию данных, чтобы он не влиял на другие объекты. Процесс создания глубокой копии дня называется detach
Так как итераторы в стиле STL концептуально просто указатели, они непосредственно изменяют базовые данные. Как следствие, неконстантные итераторы отделяются при создании с помощьюContainer::begin()
, так что другие неявно разделенные экземпляры не могут пострадать от изменений.
Итак, если сначала выполняется вызов QVector::begin()
, тогда основное хранилище контейнера перераспределяется, а последующий вызов QVector::cbegin()
возвращает тот же указатель. Однако, отмените их, и вызов QVector::cbegin()
возвращает указатель на общий хранилище до того, как произойдет перераспределение.