Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 [ 156 ] 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

ванную версию шаблона для символов типа char, а тип wstring предназначен для символов типа wchar t.

Трактовки типа символов представляют собой информацию о том, как следует постзшать в зависимости от представления типа символов. Необходимость в дополнительном классе объясняется тем, что интерфейс встроенных типов (таких, как char и wchar t) изменять нельзя, но один символьный тип может трактоваться по-разному. Дополнительная информация о классах трактовок приводится на с. 659.

В следующем фрагменте определяется специальный класс трактовок для строк, благодаря которому операции со строками выполняются без учета регистра символов;

string/icstring.hpp #ifndef ICSTRING HPP #def1ne ICSTRING HPP

#1nclude <string> #include <iostreani> #include <cctype>

/* Замена функций стандартного класса char traits<char>

* для того, чтобы операции со строками

* выполнялись без учета регистра символов */

struct 1gnorecase tra1ts public std: :char traits<char> { Проверка равенства cl и c2 static bool eq(const char& cl. const char& c2) { return std;;toupper(cl)==std:;toupper(c2);

Проверка условия "cl меньше c2" static bool lt(const char& cl. const char& c2) { return std::toupper(cl)<std::toupper(c2);

Сравнение до n символов si и s2 static int compare(const char* si. const char* s2. std::si2e t n) { for (std::size t 1=0; 1<n: ++1) ( if (!eq(sl[i].s2[i])) {

return lt(sl[11.s2[il)?-l:l;

return 0;

Поиск CBS

static const char* find(const char* s. std::si2e t n.

const char& c) { for (std;;size t 1=0: i<n: ++i) ( if (eq(s[i].c)) { return &(s[i]);



return 0:

Определение специального типа для таких строк

typedef std::basic string<char.ignorecase tra1ts> icstring;

/* Определение оператора вывода.

* так как тип трактовок отличен от типа,

* заданного для std:lOstream */

inli пе

std;;ostream& operator « (std::ostreani& strm. const icstringS s) {

Простое преобразование Icstring в обычную строку return strm « std;:string(s.data().s.length());

#end1f ICSTRING HPP

Определение оператора вывода необходимо из-за того, что стандарт описывает операторы ввода-вывода только для потоков данных, у которых тип символов соответствует типу трактовок. В данном случае мы используем другой тип трактовок, поэтому для него приходится определять собственный оператор вывода. Аналогичная проблема существует и для операторов ввода,

В следующей программе показано, как использовать специализированный вид строк:

string/icstringl.cpp #lnclude "icstring.hpp"

int mainO {

using std::COut; using std;;endl:

icstring slChallo"); icstring s2("otto"): icstring s3("hALLo");

cout « std::boolalpha:

cout « si « " == " « s2 « " : " « (sl==s2) « endl: cout « si « " == « s3 « " ; " « (sl==s3) « endl;

icstring;:size type idx = sl.find("All"); if (idx != icstring;:npos) {

cout « "index of \"A11\" in \"" « si « "\": " « idx « endl;



else {

cout « "\"А11\" not found in \"" « si « endl;

Результат выполнения программы выглядит так;

hallo »" otto : false hallo == hALLo : true index of "All" in "hallo" ; 1

3a дополнительными сведениями об интернационализации обращайтесь к главе 14.

Эффективность

Стандарт не указывает, как должен бьггь реализован строковый класс, - он лишь определяет интерфейс строкового класса. В зависимости от выбранного концептуального подхода и приоритетов реализации могут существенно различаться по скорости работы и расходованию памяти.

Если вы добиваетесь оптимизации по скорости, используйте строковый класс, основанный на ковдепции подсчета ссылок. Подсчет ссылок ускоряет копирование и присваивание, поскольку реализация копирует и присваивает не содержимое строк, а только ссылки (на с. 226 описан класс умного указателя, реализующий подсчет ссылок для произвольного типа). Хотя при подсчете ссылок передача по константной ссылке может вам не потребоваться, для обеспечения должной гибкости и переносимости программ такую передачу нужно обеспечить.

Строки и векторы

Строки имеют много общего с векторами, и это не удивительно - оба типа контейнеров обычно реализуются в виде динамических массивов. Строку можно рассматривать как специализированную разновидность вектора с символьными элементами. Более того, строки могут использоваться как контейнеры STL (см. с. 480). Впрочем, интерпретировать строку как специализированный вектор опасно, поскольку между ними существует немало принципиальных различий, главное из которых - предназначение контейнера.

О Векторы предназначены для работы с элементами контейнеров, а не с контейнером в целом. По этой причине реализации векторов оптимизируются для эффективного выполнения операций с отдельными элементами.

О Строки предназначены для работы с целым контейнером (строкой), поэтому для них оптимизируются операции присваивания и передачи всего контейнера.

Различия в целях обычно приводят к совершенно разным реализациям. Например, строки часто реализуются на базе подсчета ссылок, а для векторов такая реализация вообще нехарактерна. Впрочем, вектор может использоваться как обычная С-строка. За подробностями обращайтесь на с. 164.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 [ 156 ] 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239