Using QString Effectively/bg

From Qt Wiki
< Using QString Effectively
Revision as of 12:39, 17 April 2015 by AutoSpider (talk | contribs) (Remove non-functioning "toc" command)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
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.

Български English 简体中文


Написано от: 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 може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва алгоритъма на Бойър-Муур за да извърши бързо търсене.