Какова внутренняя структура данных QVarLengthArray?
Например, если у меня есть:
QVarLengthArray<QString> anArray;
QString string1 = "whatever";
QString string2 = "something else";
anArray[0] = string1;
anArray[1] = string2;
Легко ли предварительно вычислить & anArray [1], данный & anArray?
Я просматривал исходный код QVarLengthArray, пытаясь понять, как QVarLengthArray хранит массив QStrings в памяти. Насколько мне нравится Qt, одна вещь, которая особенно болезненна для меня, - это ее непрозрачная основа указателя. (Вспомогательные функции в помощи отладчика в некоторых случаях, но когда вы действительно пытаетесь вникнуть во внутренние элементы, непрозрачные указатели скрывают большую информацию, которая в противном случае была бы доступна в отладчике.)
Я нашел пару статей "Qt Internals" на codeproject.com и в других местах, но никто не помог.
В общем, было бы здорово иметь возможность заглянуть в реальные структуры данных за непрозрачными указателями, но для непосредственной необходимости было бы прекрасно понять, есть ли хороший способ предсказать начальный адрес каждого элемента в QVarLengthArray из MyClass, который содержит указатели, QStrings и целые числа.
(Имея эту информацию, вы сможете упростить собственную сериализацию. Я понимаю риски повторного использования и готов принять эти риски для этого эксперимента.)
Посмотрите под "частным" разделом заголовков классов, чтобы найти переменные-члены - они расскажут вам о структуре класса. Здесь ссылка на первый член QVarLengthArray: http://code.woboq.org/qt5/qtbase/src/corelib/tools/qvarlengtharray.h.html#QVarLengthArray::a
В Qt 5 QVarLengthArray начинается с 2 ints, за которым следует указатель на первый элемент в массиве, за которым следует объединение, которое содержит собственно массив, предварительно выделенный в стеке.
Если размер вашего массива меньше или равен предварительно распределенной емкости, то &(array[1])
является просто фиксированным числом байтов после &anArray
. Однако, если ваш массив будет больше, чем предварительно распределенная емкость, тогда QVarLengthArray вместо этого переключится на кучу. Когда это произойдет, больше нет отношения между &(array[1])
и &anArray
.
Если у вас есть &anArray
, надежный способ найти &(anArray[1])
выглядит следующим образом:
QString* anArray_0 = (&anArray)->begin(); // &(anArray[0])
QString* anArray_1 = anArray_0 + 1; // &(anArray[1])
Или, чтобы сделать это низкоуровневым способом без вызова каких-либо функций-членов (при условии, что нет отступов):
// Use reinterpret_cast to enable 1-byte pointer arithmetic
char* outerPtr = reinterpret_cast<char*>(&anArray);
QString* anArray_0 = reinterpret_cast<QString*>( outerPtr + 2*sizeOf(int) ); // &(anArray[0])
QString* anArray_1 = anArray_0 + 1; // &(anArray[1])
(Имея эту информацию, вы сможете упростить собственную сериализацию. Я понимаю риски повторного использования и готов принять эти риски для этого эксперимента.)
Qt обещает source- и двоичную совместимость между малыми выпусками. Структура QVarLengthArray гарантированно останется неизменной до Qt 6, по крайней мере.
В общем, было бы здорово иметь возможность заглянуть в реальные структуры данных за непрозрачными указателями
Я считаю, что Woboq Code Browser очень полезен для этого - исходный код становится интерактивной сетью гиперссылок, и вы можете искать любой класс в библиотеке. Просто загляните в заголовок класса, чтобы найти непрозрачный указатель, и нажмите на него.