Using QString Effectively/bg: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(No difference)

Revision as of 06:58, 24 February 2015


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

[toc align_right="yes" depth="1"]

Написано от: Girish Ramakrishnan, ForwardBias Technologies

Тази статия обяснява предназначението на различните класове свързани с QString.

QLatin1String : Избягване на скрито заделяне на памет в оператора "=="

Създаването на QString от char масив може да предизвика заделяне на памет. Пример:

<br /> if (fruit == &quot;apple&amp;quot;) {  } // вероятно заделяне на памет<br />

QString предоставя QString::operator==(const char *) за сравняване със C-стрингове. Както е обяснено в "QtString&quot;:http://developer.qt.nokia.com/wiki/QtStrings/, кодировката на C-стринговете се определя като се използва QTextCodec::setCodecForCStrings(). Когато не е сложено специално кодиране, Qt изпълнява горното сравнение като предоставя специализирана функция, която сравнява Уникод стринга (fruit) и Latin-1 стринга ('apple'). Това сравнение е бързо и не изисква заделяне на памет.

Обаче, когато QTextCodec::setCodecForCString е нагласен, "apple&quot; се конвертира в QString като се използва QString::fromAscii(). Това означава, че QString ще задели памет за стринга "apple&quot; и ще създаде копие на C масива преди да изпълни сравнението!

Разработчиците на приложения нагласяват QTextCodec::setCodecForCString() в main() без да осъзнават, че това има страничен ефект и причинява заделяне на памет за всеки един C-стринг при сравнение.

Тъй като сравняването с Latin-1 C-стрингове е често срещано в програмите, Qt предоставя специален клас, наречен QLatin1String, който просто съдържа указател към C-стринг с Latin-1 кодировка. В допълнение, QString предоставя и оператора QString::operator(const QLatin1String &amp;), който извиква специална функция, която сравнява Уникод стринг и Latin1 стринг. Можем да направим горният код без съмнение по-бърз като напишем: <code>

   if (fruit QLatin1String("apple&quot;)) { … } // бърз и оказва кодировката

В кода на 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. И след това има още едно заради добавянето на ")". Броят на заделянията се увеличава при всяко следващото извикване на оператора "".

<br /> if (foo.startsWith(&quot;(&quot;'' type + &quot;)&quot;))<br />

Допълнителните заделяния на памет могат да бъдат избегнати ако дължината на крайният QString се знае предварително. Qt 4.6 въведе вътрешния клас QStringBuilder, който "резервира&quot; памет за събирането на един път. Той постига това като при всяко използване на оператора + по-горе се връща различена клас (не QString). Този клас следи какви стрингове се добавят и колко памет е нужна за тях на всяка стъпка. На края, когато операцията по обединяването се конвертира обратно в QString, класа заделя памет и копира всички стрингове един след друг. Тази възможност може да бъде включена като се използва QT_USE_FAST_CONCATENATION. Когато това е дефинирано, можете да използвате оператора вместо ''. Пример:

<br /> if (foo.startsWith(&quot;(&quot; % type % &quot;)&quot;))<br />


'' може да се използва вместо като се дефинира QT_USE_FAST_OPERATOR_PLUS. Вижте "Fast concatenation&quot;:http://doc.qt.nokia.com/4.6/qstring.html#more-efficient-string-construction за повече детайли

QStringMatcher : Бързо търсена на стринг в стринг

QStringMatcher може да се използва за търсене на стринг многократно в множество стрингове и в един стринг много пъти. Класът използва "алгоритъма на Бойър-Муур&quot;:http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm за да извърши бързо търсене.