ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 8) онлайн
Преобразования строк в объекты класса string и наоборот
Рассмотрим другой пример, в котором использованы конструктор с одним аргу- ментом и оператор преобразования. Здесь используется класс String, который мы видели в примере STRPLUS ранее в этой главе.
// strconv.cpp
// перевод обычных строк в класс String #include <iostream> using namespace std;
#include <string.h> // для функций str*
///////////////////////////////////////////////////////////
class String
{
private:
enum { SZ = 80 }; // размер массива
char str [ SZ ]; // массив для хранения строки
public:
// конструктор без параметров
String ( )
{ str [ 0 ] = '\x0'; }
// конструктор с одним параметром
String ( char s [ ] )
{ strcpy ( str, s ); } // сохраняем строку в массиве
// показ строки
void display ( ) const
{ cout << str; }
// перевод строки к обычному типу
operator char* ( )
{ return str; }
};
///////////////////////////////////////////////////////////
int main ( )
{
String s1; // используем конструктор без параметров
char xstr [ ] = "Ура, товарищи! "; // создаем обычную строку
s1 = xstr; // неявно используем конструктор с одним параметром
s1.display ( ); // показываем строку
String s2 = "Мы победим!"; // снова используем конструктор с параметром
cout << static_cast<char*>( s2 ); // используем оператор перевода типа
cout << endl;
return 0;
}
Конструктор с одним аргументом преобразовывает обыкновенную строку (массив элементов типа char) в объект класса String:
String ( char s [ ] ) { strcpy ( str, s ); }
Строка передается в качестве аргумента и копируется в переменную клас- са str заново созданного объекта класса String, используя библиотечную функ- цию strcpy().
Это преобразование будет применено, когда создается объект класса String
String s2 = "Мы победим!";
или будет применено в выражении присваивания
s1 = xstr;
где s1 — объект класса String, а переменная xstr — просто строка.
Операция преобразования используется для перевода объекта класса String в строку:
operator char* ( ) { return str; }
Звездочка в этом выражении означает указатель на. Мы не будем вдаваться в объяснения указателей до главы 10, но их использование нетрудно понять. Это означает указатель на char, что почти то же, что и массив типа char. То есть запись char* — почти то же, что char[]. Это просто другой способ объявления пе- ременной строкового типа.
Оператор преобразования используется компилятором в строке
cout << static_cast<char*>( s2 );
Здесь s2 — переменная, использованная в качестве аргумента для перегру- женной операции <<. Так как операции << ничего не известно об определенном пользователем типе String, то компилятор будет пытаться преобразовать пере- менную s2 к одному из известных ему типов. Мы определяем тип, к которому хотим преобразовать переменную, с помощью оператора static_cast для char*. Оператор ищет преобразование от типа String к строковому типу и, найдя нашу функцию char*(), использует ее для генерации строки, которая затем будет вы- ведена через операцию <<. (Результат похож на вызов метода String::display(), но делает легким и интуитивно понятным вывод с помощью операции <<, а метод display() будет уже лишним и может быть удален.)
Вот результат работы программы STRCONV:
Ура. товарищи! Мы победим!
Пример STRCONV демонстрирует, что преобразование типов происходит авто- матически не только в выражениях присваивания, но и в других подходящих местах, таких, как пересылка аргументов операциям (например, <<) или функ- циям. При передаче в операцию или функцию аргумента неправильного типа, они преобразуют его к приемлемому типу, если вы определили такое преобразо- вание.
Заметим, что вы не можете использовать явное выражение присваивания для преобразования объекта класса String к переменной строкового типа:
xstr = s2;
Строка xstr — это массив, и вы не можете ничего ему присвоить (хотя, как мы увидим в главе 11, если мы перегрузим операцию присваивания, то все ста- нет возможным).
12 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
