Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.
Using QString Effectively/bg
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine. Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean. |
Написано от: Girish Ramakrishnan, ForwardBias Technologies
Тази статия обяснява предназначението на различните класове свързани с QString.
QLatin1String : Избягване на скрито заделяне на памет в оператора "=="
Създаването на QString от char масив може да предизвика заделяне на памет. Пример:
if (fruit == "apple") { … } // вероятно заделяне на памет
QString предоставя QString::operator==(const char *) за сравняване със C-стрингове. Както е обяснено в QtString, кодировката на C-стринговете се определя като се използва QTextCodec::setCodecForCStrings(). Когато не е сложено специално кодиране, Qt изпълнява горното сравнение като предоставя специализирана функция, която сравнява Уникод стринга (fruit) и Latin-1 стринга ('apple'). Това сравнение е бързо и не изисква заделяне на памет.
Обаче, когато QTextCodec::setCodecForCString е нагласен, "apple" се конвертира в QString като се използва QString::fromAscii(). Това означава, че QString ще задели памет за стринга "apple" и ще създаде копие на C масива преди да изпълни сравнението!
Разработчиците на приложения нагласяват QTextCodec::setCodecForCString() в main() без да осъзнават, че това има страничен ефект и причинява заделяне на памет за всеки един C-стринг при сравнение.
Тъй като сравняването с Latin-1 C-стрингове е често срещано в програмите, Qt предоставя специален клас, наречен QLatin1String, който просто съдържа указател към C-стринг с Latin-1 кодировка. В допълнение, QString предоставя и оператора QString::operator(const QLatin1String &), който извиква специална функция, която сравнява Уникод стринг и Latin1 стринг. Можем да направим горният код без съмнение по-бърз като напишем:
if (fruit QLatin1String("apple")) { … } // бърз и оказва кодировката
В кода на Qt, всички сравнения със C-стрингове използват QLatin1String, тъй като приложението може да избере произволен кодек за C-стринговете си.
QStringRef : Обработка на стрингове без заделяне на памет
QString има множество методи за обработка на стрингове като mid(), left(), right(). Всички те създават нов QString и следователно заделя и копират данни от съществуващия QString. Вместо това могат да се използват QString::midRef(), QString::leftRef() и QString::rightRef(), за да се получи QStringRef. QStringRef е връзка към част от QString. QString също предоставя много предефинирани операции като QString::operator==(const QStringRef &) за оптимална употреба с QStringRef.
QString::reserve и QString::squeeze
По-добре е да заделите повече памет предварително с QString::reserve, така че всяко извикване на QString::append() да не причинява ново заделяне. Допълнителната памет може да освободи по-късно с QString::squeeze.
QStringBuilder : Бързо обединяване на QString-ове
Кода по-долу изисква поне 2 заделяния на памет. Първото заделяне е за да се съхрани резултата от "(" + type. И след това има още едно заради добавянето на ")". Броят на заделянията се увеличава при всяко следващото извикване на оператора "".
if (foo.startsWith("("'' type + ")"))
Допълнителните заделяния на памет могат да бъдат избегнати ако дължината на крайният QString се знае предварително. Qt 4.6 въведе вътрешния клас QStringBuilder, който "резервира" памет за събирането на един път. Той постига това като при всяко използване на оператора + по-горе се връща различена клас (не QString). Този клас следи какви стрингове се добавят и колко памет е нужна за тях на всяка стъпка. На края, когато операцията по обединяването се конвертира обратно в QString, класа заделя памет и копира всички стрингове един след друг. Тази възможност може да бъде включена като се използва QT_USE_FAST_CONCATENATION. Когато това е дефинирано, можете да използвате оператора вместо ''. Пример:
if (foo.startsWith("(" % type % ")"))
'' може да се използва вместо като се дефинира QT_USE_FAST_OPERATOR_PLUS. Вижте Fast concatenation за повече детайли
QStringMatcher : Бързо търсена на стринг в стринг
QStringMatcher може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва алгоритъма на Бойър-Муур за да извърши бързо търсене.