Оператору вывода необходим доступ к внутреннему представлению строки String. Так как operator не является функцией-членом, он не имеет доступа к закрытому члену данных _string. Ситуацию можно разрешить двумя способами: объявить operator дружественным классу String, используя ключевое слово friend (дружественные отношения рассматриваются в разделе 15.2), или реализовать встраиваемую (inline) функцию для доступа к этому члену. В нашем случае уже есть такая функция: c_str() обеспечивает доступ к внутреннему представлению строки. Воспользуемся ею при реализации операции вывода:
inline ostream
operator( ostream os, const String s )
{
return os s.c_str();
}
Ниже приводится пример программы, использующей класс String. Эта программа берет слова из входного потока и подсчитывает их общее число, а также количество слов "the" и "it" и регистрирует встретившиеся гласные.
#include iostream
#include "String.h"
int main() {
int aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0,
theCnt = 0, itCnt = 0, wdCnt = 0, notVowel = 0;
// Слова "The" и "It"
// будем проверять с помощью operator==( const char* )
String but, the( "the" ), it( "it" );
// operator( ostream, String )
while ( cin buf ) {
++wdCnt;
// operator( ostream, const String )
cout buf ' ';
if ( wdCnt % 12 == 0 )
cout endl;
// String::operator==( const String ) and
// String::operator==( const char* );
if ( buf == the | | buf == "The" )
++theCnt;
else
if ( buf == it || buf == "It" )
++itCnt;
// invokes String::s-ize()
for ( int ix =0; ix buf.sizeO; ++ix )
{
// invokes String:: operator [] (int)
switch( buf[ ix ] )
{
case 'a': case 'A': ++aCnt; break;
case 'e': case 'E': ++eCnt; break;
case 'i': case 'I': ++iCnt; break;
case 'o': case '0': ++oCnt; break;
case 'u': case 'U': ++uCnt; break;
default: ++notVowe1; break;
}
}
}
// operator( ostream, const String )
cout "\n\n"
"Слов: " wdCnt "\n\n"
"the/The: " theCnt '\n'
"it/It: " itCnt "\n\n"
"согласных: " notVowel "\n\n"
"a: " aCnt '\n'
"e: " eCnt '\n'
"i: " ICnt '\n'
"o: " oCnt '\n'
"u: " uCnt endl;
}
Протестируем программу: предложим ей абзац из детского рассказа, написанного одним из авторов этой книги (мы еще встретимся с этим рассказом в главе 6). Вот результат работы программы:
Alice Emma has long flowing red hair. Her Daddy says when the
wind blows through her hair, it looks almost alive, 1ike a fiery
bird in flight. A beautiful fiery bird, he tells her, magical but
untamed. "Daddy, shush, there is no such thing," she tells him, at
the same time wanting him to tell her more. Shyly, she asks,
"I mean, Daddy, is there?"
Слов: 65
the/The: 2
it/It: 1
согласных: 190
a: 22
e: 30
i: 24
о: 10
u: 7
В наших реализациях конструкторов и операций присваивания содержится много повторов. Попробуйте вынести повторяющийся код в отдельную закрытую функцию-член, как это было сделано в разделе 2.3. Убедитесь, что новый вариант работоспособен.
Модифицируйте тестовую программу так, чтобы она подсчитывала и согласные b, d, f, s, t.
Напишите функцию-член, подсчитывающую количество вхождений символа в строку String, используя следующее объявление:
class String {
public:
// ...
int count( char ch ) const;
// ...
};
Реализуйте оператор конкатенации строк (+) так, чтобы он конкатенировал две строки и возвращал результат в новом объекте String. Вот объявление функции:
class String {
public:
// ...