Страница 95. Имелось ввиду, что в разделе “Подсчет значений” в строке кода qCount(list, “mantus”, n) строку “mantus” надо набирать с заглавной буквы. Если набрать как в книге, то алгоритм qCount не находит в списке ничего и “На экране появится цифра 0.”.
В пункте “Регулярные выражения” в таблице 4.13 в описания к круглым скобкам сказано про сохранение в памяти группы найденных символов, но не показывается, как получать к этой группе доступ.
Начало раздела “Алгоритмы”, пример использования алгоритма qCopy. Правильно ли я понимаю, что строка sizeof(QString) возвращает размер (в байтах) указателя на строку, а sizeof(values) – суммарный размер всех указателей в массиве?
На странице 85 поставило в ступор использование класса QValueList для итератора ::iterator it = list.begin();
Qt Creator таких ключевых слов и заголовочных файлов не знает.
Мне подсказали, что это было в qt3.
Возможно, опечатка?
Спасибо Александр за найденную ошибку.
QValueList это “гость” из старого издания, правильно должно быть QList::iterator it = list.begin();
В следующем издании обязательно исправлю.
Стр. 99, проверка числа от 0 до 999
регулярное выражение в книге: ^\d+\d?\d?$ не отсеивает числа более 999.
выражение должно быть либо: ^\d{1,3}$, либо ^\d\d?\d?$
Спасибо, Вы правы, если нужно ограничение [0-999], как это упоминается в книге, то из регулярного выражения нужно убрать “+”, то есть регулярное выражение должно выглядеть так “^\\d\\d?\\d?$”.
Уважаемый Макс! Извиняюсь, что оставляю так много комментариев, просто по мере изучения главы возникают новые вопросы и я стараюсь сразу их обозначить, чтобы потом не забыть… В таблице 4.13 немного смущает описание символа регулярного выражения “^”, а именно: “В начале набора символов означает любой символ, не вошедший в набор”. Как я понял, этот символ означает начало символьного выражения? И еще, сначала не смог понять пример с числом от 0 до 999, т.к. в таблице 4.13 говорится, что символ “\d” – это любое число, в итоге разобрался. По моему мнению, правильнее было бы написать, что “\d” – это либо любая цифра, либо число от 0 до 9…
Вячеслав! Большое спасибо за комментарии, оставляйте их дальше я им буду только рад!
С символом “^” имелось в виду, что когда этот символ стоит первым в регулярном выражении, то это означает, что регулярное выражение должно совпадать с начала строки.
Про “\d” можно если “любая цифра” не совсем понятно, то вместо этого написать “число от 0 до 9”.
Макс, спасибо большое за ответы и за отличную обратную связь!
Я имел ввиду, что в книге написано именно \d – “любое ЧИСЛО”, это меня и смутило, потому-что числом может быть и 0, и 5, и 99 и т.д. Поэтому в таблице 4.13, по моему мнению, правильнее было бы написать “цифра”, либо “число от 0 до 9”.
Согласен, думаю “число от 0 до 9” будет более понятно.
Приветствую Макс. Прочитал главу и не понял почему тип QList отнесен к спискам. Судя по описанию это получается частный случай вектора, в котором хранятся указатели.
Страница 81, таблица 4.1. QList – доступ быстро. Но если это односвязный список, то доступ к нему совсем не быстро (тем более, далее в главе Вы пишете, что для по иска лучше использовать вектор.
Павел, в таблице 4.1 ничего не сказано про скорость доступа. Если Вы имели ввиду таблицу 4.4, то в столбце “Доступ” так и указанно QList – Быстро, QLinkedList – Медленно. Может я не правильно понял Ваш комментарий, если Вы имели в виду, что-то другое, то сформулируйте его иначе. Спасибо.
Здравствуйте, Макс! Опечатался, конечно, Таблица 4.4, колонка “Доступ” первой строки. Но на стр.84 первый абзац, последнее предложение, говорит об обратном. Или по “доступом” имелось ввиду что-то другое? Спасибо большое!
Здравствуйте, Павел! Под доступом имеются ввиду метод at() и operator[]. Контейнер QList очень хорошо оптимизирован и использует массив указателей, который гарантирует быстрый доступ к элементам по индексу. На 84 странице Вас видимо смутила формулировка “Плохо приспособлен для поиска определенного элемента по индексу”. Тут имелось ввиду, что она может быть хуже чем при использовании контейнера QVector, так как в векторе доступ к элементу, в идеальном случае, производится напрямую. Надеюсь немного прояснил.
Спасибо за ответ, Макс! Тогда получается, что QList – это больше вектор (как, например, в c#), чем связанный список и отличается от него только двойной операцией доступа (в начале – адрес объекта, потом сам объект). Или вовсе не так? Спасибо
Здравствуйте, Макс! На стр. 93 приводится в пример вариант использования функции qSort() с тремя параметрами. Но при сборке компилятор ругается на третий параметр функции, на то, что он не определен (caseLessThan, либо caseInsensitiveLessThan). Если реализовать один из этих параметров как собственную функцию, то функция qSort() работает.
Спасибо Вячеслав! Очень хороший комментарий! QtAlgorithms я проверял на Qt5.10, если Вы используете версию Qt выше то вполне возможно есть расхождения. Так же нашел в документации информацию, о том что QtAlgorithms теперь существуют для поддержания кода ранее написанных программ и их рекомендуется заменять алгоритмы Qt на эквиваленты из STL. Например: qSort(container.begin(), container.end(), qLess()) на std::sort(container.begin(), container.end(), qLess())
У меня версия 5.11 под Linux. А по поводу QtAlgorithms, т. е. есть риск, что в следующих обновлениях библиотеки Qt может не быть поддержки этих алгоритмов? Это касается всей библиотеки Tulip?
Здравствуйте, Макс! На стр. 101-102 вами описывается принцип shared data, в конце стр. 101 приводится описание четырех шагов использования общих данных. А в начале стр. 102 описывается что бы произошло при дополнительных действиях пятым шагом:
“Если бы мы пятым шагом изменили данные второго объекта, то после создания копии для новых данных счетчик ссылок старых данных уменьшился бы до значения 0, и это привело бы к освобождению памяти и уничтожению старых данных.”
Но разве в данной ситуации, на пятом шаге, при изменении второго объекта будет произведено копирование данных и удаление старых? Ведь согласно документации https://doc.qt.io/qt-5/implicit-sharing.html#implicit-sharing-in-detail “Implicit sharing automatically detaches the object from a shared block if the object is about to change and the reference count is greater than one.”, “отсоединение” происходит если счетчик ссылок больше 1, но в данной ситуации он именно равен 1. И эти данные можно использовать без копирования.
Прошу прощения, если неправильно понял.
Алексей спасибо за вопрос,
на странице 102 написан код для иллюстрации, я имел ввиду, в качестве пятого шага добаление еще одной строки в этот код
str2 += ” добавленно изменение”;
то в этом случае ни один из объектов строк больше не ссылался бы на “Новая строка”, а его динамическая копия, созданная в объекте QString, была бы разрушена.
Большое спасибо Stephen. Этот конструктор нужно будет заменить на “QByteArray arr(З, 0)”, в первом параметре указываем размер, а во втором значение для его заполнения.
QList list;
list << 10 << 20 << 30;
QValueList::iterator it = list.begin();
while (it 1= list.end()) {
qDebug() << "Element:" << *it; ++it;
}
Я нашел информацию о QValueList только в архиве для Qt 3.3 и на форумах 2006 года, также этот класс не содержится в QtCore. Не лучше ли тут использовать
Подсчёт значений
На экране появится цифра 0.
Я не нашел. Пожалуйста укажите место или страницу книги где появится цифра 0.
Страница 95. Имелось ввиду, что в разделе “Подсчет значений” в строке кода qCount(list, “mantus”, n) строку “mantus” надо набирать с заглавной буквы. Если набрать как в книге, то алгоритм qCount не находит в списке ничего и “На экране появится цифра 0.”.
Сергей, да вы правы это опечатка. Должно быть qCount(list, “Mantus”, n);
Спасибо!
В пункте “Регулярные выражения” в таблице 4.13 в описания к круглым скобкам сказано про сохранение в памяти группы найденных символов, но не показывается, как получать к этой группе доступ.
Серафим, на странице 99 есть пример использования круглых скобок с QRegExp rxp(“(.com|.ru)”), надеюсь он прояснит ситуацию.
Начало раздела “Алгоритмы”, пример использования алгоритма qCopy. Правильно ли я понимаю, что строка sizeof(QString) возвращает размер (в байтах) указателя на строку, а sizeof(values) – суммарный размер всех указателей в массиве?
Сергей, да правильно. Тем самым разделив sizeof(values) на sizeof(QString) мы получим количество строк входящих в массив values.
На странице 85 поставило в ступор использование класса QValueList для итератора ::iterator it = list.begin();
Qt Creator таких ключевых слов и заголовочных файлов не знает.
Мне подсказали, что это было в qt3.
Возможно, опечатка?
Спасибо Александр за найденную ошибку.::iterator it = list.begin();
QValueList это “гость” из старого издания, правильно должно быть QList
В следующем издании обязательно исправлю.
Стр. 99, проверка числа от 0 до 999
регулярное выражение в книге: ^\d+\d?\d?$ не отсеивает числа более 999.
выражение должно быть либо: ^\d{1,3}$, либо ^\d\d?\d?$
Спасибо, Вы правы, если нужно ограничение [0-999], как это упоминается в книге, то из регулярного выражения нужно убрать “+”, то есть регулярное выражение должно выглядеть так “^\\d\\d?\\d?$”.
Уважаемый Макс! Извиняюсь, что оставляю так много комментариев, просто по мере изучения главы возникают новые вопросы и я стараюсь сразу их обозначить, чтобы потом не забыть… В таблице 4.13 немного смущает описание символа регулярного выражения “^”, а именно: “В начале набора символов означает любой символ, не вошедший в набор”. Как я понял, этот символ означает начало символьного выражения? И еще, сначала не смог понять пример с числом от 0 до 999, т.к. в таблице 4.13 говорится, что символ “\d” – это любое число, в итоге разобрался. По моему мнению, правильнее было бы написать, что “\d” – это либо любая цифра, либо число от 0 до 9…
Вячеслав! Большое спасибо за комментарии, оставляйте их дальше я им буду только рад!
С символом “^” имелось в виду, что когда этот символ стоит первым в регулярном выражении, то это означает, что регулярное выражение должно совпадать с начала строки.
Про “\d” можно если “любая цифра” не совсем понятно, то вместо этого написать “число от 0 до 9”.
Макс, спасибо большое за ответы и за отличную обратную связь!
Я имел ввиду, что в книге написано именно \d – “любое ЧИСЛО”, это меня и смутило, потому-что числом может быть и 0, и 5, и 99 и т.д. Поэтому в таблице 4.13, по моему мнению, правильнее было бы написать “цифра”, либо “число от 0 до 9”.
Согласен, думаю “число от 0 до 9” будет более понятно.
Приветствую Макс. Прочитал главу и не понял почему тип QList отнесен к спискам. Судя по описанию это получается частный случай вектора, в котором хранятся указатели.
Здравствуйте Антон! Помимо указателей в QList хранятся еще значения элементов, такой тип данных получил название список.
Получается в этом типе используется 2 массива, один с указателями, а другой со значениями? Или это односвязный список?
Да Антон, именно так, QList это односвязный список.
Страница 81, таблица 4.1. QList – доступ быстро. Но если это односвязный список, то доступ к нему совсем не быстро (тем более, далее в главе Вы пишете, что для по иска лучше использовать вектор.
Павел, в таблице 4.1 ничего не сказано про скорость доступа. Если Вы имели ввиду таблицу 4.4, то в столбце “Доступ” так и указанно QList – Быстро, QLinkedList – Медленно. Может я не правильно понял Ваш комментарий, если Вы имели в виду, что-то другое, то сформулируйте его иначе. Спасибо.
Здравствуйте, Макс! Опечатался, конечно, Таблица 4.4, колонка “Доступ” первой строки. Но на стр.84 первый абзац, последнее предложение, говорит об обратном. Или по “доступом” имелось ввиду что-то другое? Спасибо большое!
Здравствуйте, Павел! Под доступом имеются ввиду метод at() и operator[]. Контейнер QList очень хорошо оптимизирован и использует массив указателей, который гарантирует быстрый доступ к элементам по индексу. На 84 странице Вас видимо смутила формулировка “Плохо приспособлен для поиска определенного элемента по индексу”. Тут имелось ввиду, что она может быть хуже чем при использовании контейнера QVector , так как в векторе доступ к элементу, в идеальном случае, производится напрямую. Надеюсь немного прояснил.
Спасибо за ответ, Макс! Тогда получается, что QList – это больше вектор (как, например, в c#), чем связанный список и отличается от него только двойной операцией доступа (в начале – адрес объекта, потом сам объект). Или вовсе не так? Спасибо
Павел, просто рассматривайте контейнер QList как список оптимизированный для индексации.
До этого думал, что вектор эффективнее, чем список. Может я не так понял или в qt используется другой подход? Вектор не базируется на списке?
Да, в Qt реализован свой собственный подход для QList и этот класс не базируется на QVector .
Здравствуйте, Макс! На стр. 93 приводится в пример вариант использования функции qSort() с тремя параметрами. Но при сборке компилятор ругается на третий параметр функции, на то, что он не определен (caseLessThan, либо caseInsensitiveLessThan). Если реализовать один из этих параметров как собственную функцию, то функция qSort() работает.
Спасибо Вячеслав! Очень хороший комментарий! QtAlgorithms я проверял на Qt5.10, если Вы используете версию Qt выше то вполне возможно есть расхождения. Так же нашел в документации информацию, о том что QtAlgorithms теперь существуют для поддержания кода ранее написанных программ и их рекомендуется заменять алгоритмы Qt на эквиваленты из STL. Например: qSort(container.begin(), container.end(), qLess()) на std::sort(container.begin(), container.end(), qLess ())
У меня версия 5.11 под Linux. А по поводу QtAlgorithms, т. е. есть риск, что в следующих обновлениях библиотеки Qt может не быть поддержки этих алгоритмов? Это касается всей библиотеки Tulip?
Это касается только QtAlgorithms
На стр. 98, нижний абзац, опечатка, имеется ввиду не таблица 4.11, а таблица 4.13.
Спасибо, за еще одну найденную опечатку!
И далее в этом разделе указана таблица 4.11, а не 4.13.
Спасибо, я нашел еще две опечатки где стоит 4.11, вместо 4.13
Здравствуйте, Макс! На стр. 101-102 вами описывается принцип shared data, в конце стр. 101 приводится описание четырех шагов использования общих данных. А в начале стр. 102 описывается что бы произошло при дополнительных действиях пятым шагом:
“Если бы мы пятым шагом изменили данные второго объекта, то после создания копии для новых данных счетчик ссылок старых данных уменьшился бы до значения 0, и это привело бы к освобождению памяти и уничтожению старых данных.”
Но разве в данной ситуации, на пятом шаге, при изменении второго объекта будет произведено копирование данных и удаление старых? Ведь согласно документации https://doc.qt.io/qt-5/implicit-sharing.html#implicit-sharing-in-detail “Implicit sharing automatically detaches the object from a shared block if the object is about to change and the reference count is greater than one.”, “отсоединение” происходит если счетчик ссылок больше 1, но в данной ситуации он именно равен 1. И эти данные можно использовать без копирования.
Прошу прощения, если неправильно понял.
Алексей спасибо за вопрос,
на странице 102 написан код для иллюстрации, я имел ввиду, в качестве пятого шага добаление еще одной строки в этот код
str2 += ” добавленно изменение”;
то в этом случае ни один из объектов строк больше не ссылался бы на “Новая строка”, а его динамическая копия, созданная в объекте QString, была бы разрушена.
Глава про QByteArray.
QByteArray arr(З);
Такого конструктора нет в Qt 5.12.6. Понимаю, что книга про 5.10, но решил упомянуть для будущих изданий.
Большое спасибо Stephen. Этот конструктор нужно будет заменить на “QByteArray arr(З, 0)”, в первом параметре указываем размер, а во втором значение для его заполнения.
Глава Списки QList и QLinkedList.
Пример:
QList list;
list << 10 << 20 << 30;
QValueList::iterator it = list.begin();
while (it 1= list.end()) {
qDebug() << "Element:" << *it; ++it;
}
Я нашел информацию о QValueList только в архиве для Qt 3.3 и на форумах 2006 года, также этот класс не содержится в QtCore. Не лучше ли тут использовать
QList::const_iterator it = list.constBegin();
?
Да, Штефан именно так.