Освой самостоятельно С++ за 21 день.
Шрифт:
19: friend ostream& operator<<
20: (ostream& theStream,String& theString);
21: // Общие методы доступа
22: int GetLenconst { return itsLen; }
23: const char * GetString const { return itsString; }
24:
25: private:
26: String (int); // закрытый конструктор
27: char * itsString;
28: unsigned short itsLen;
29: };
30:
31:
32: // конструктор, заданный no умолчанию, создает строку длиной 0 байт
33: String::String
34: {
35: itsString = new char[1];
36: itsString[0] = '\0' ;
37: itsLen=0;
38: // cout << "\tDefault string constructor\n";
39: // ConstructorCount++;
40: }
41:
42: //
43: // методами класса для создания новой строки
44: // указанного размера, заполненной значениями NULL.
45: String::String(int len)
46: {
47: itsString = new char[k:.H];
48: for (int i = 0; i<=len; i++)
49: itsString[i] = '\0';
50: itsLen=len;
51: // cout << "\tString(int) constructor\n";
52: // ConstructorCount++;
53: }
54:
55: // Преобразует массив символов в строку
56: String::String(const char * const cString)
57: {
58: itsLen = strlen(cString);
59: itsString = new char[itsLen+1];
60: for (int i = 0; i<itsLen; i++)
61: itsString[i] = cString[i];
62: itsString[itsLen]='\0';
63: // cout << "\tString(char*) constructor\n";
64: // ConstructorCount++;
65: }
66:
67: // конструктор-копировщик
68: String::String (const String & rhs)
69: {
70: itsLen=rhs.GetLen;
71: itsString = new char[itsLen+1];
72: for (int i = 0; i<itsLen;i++)
73: itsString[i] = rhs[i];
74: itsString[itsLen] = '\0';
75: // cout << "\tString(String&) constructor\n";
76: // ConstructorCount++;
77: }
78:
79: // деструктор освобождает занятую память
80: String::~String
81: {
82: delete [] itsString;
83: itsLen = 0;
84: // cout << "\tString destructor\n";
85: }
86:
87: // оператор равенства освобождает память, а затем
88: // копирует строку и размер
89: String& String::operator=(const String & rhs)
90: {
91: if (this == &rhs)
92: return *this;
93: delete [] itsString;
94: itsLen=rhs.GetLen;
95: itsString = new char[itsLen+1];
96: for (int i = 0; i<itsLen;i++)
97: itsString[i] = rhs[i];
98: itsString[itsLen] = '\0';
99: return *this;
100: // cout << "\tString operator=\n";
101: }
102:
103: // неконстантный
оператор индексирования,104: // возвращает ссылку на символ, который можно
105: // изменить!
106: char & String::operator[](int offset)
107: {
108: if (offset > itsLen)
109: return itsString[itsLen-1];
110: else
111: return itsString[offset];
112: }
113:
114: // константный оператор индексирования,
115: // используется для константных объектов (см. конструктор-копировщик!)
116: char String::operator[](int offset) const
117: {
118: if (offset > itsLen)
119: return itsString[itsLen-1];
120: else
121: return itsString[offset];
122: }
123:
124: // создает новую строку, добавляя текущую
125: // строку к rhs
126: String String::operator+(const String& rhs)
127: {
12S: int totalLen = itsLen + rhs.GetLen;
129: String temp(totalLen);
130: int i, j;
131: for (i = 0; i<itsLen; i++)
132: temp[i] = itsString[i];
133: for (j = 0; j<rhs.GetLen; j++, i++)
134: temp[i] = rhs[];
135: temp[totalLen]='\0';
136: return temp;
137: }
138:
139: // изменяет текущую строку, ничего не возвращая
140: void String::operator+=(const String& rhs)
141: {
142: unsigned short rhsLen = rhs.GetLen;
143: unsigned short totalLen = itsLen + rhsLen;
144: String temp(totalLen);
145: int i, j;
146: for (i = 0; i<itsLen; i++)
147: temp[i] = itsString[i];
148: for (j = 0, i = 0; j<rhs.GetLen; j++, i++)
149: temp[i] = rhs[i-itsLen];
150: temp[totalLen]='\0' ;
151: *this = temp;
152: }
153:
154: // int String::ConstructorCount =
155: ostream& operator<< ( ostream& theStream,String& theString)
156: {
157: theStream << theString.itsString; 158: return theStream;
159: }
160:
161: int main
162: {
163: String theString("Hello world.");
164: cout << theString;
165: return 0;
166: }
Результат:
Hello world.
Анализ: В строке 19 operator<< объявляется как функция-друг, которая принимает ссылки на ostream и String и возвращает ссылку на ostream. Обратите внимание, что она не является функцией-членом класса String. Поскольку эта функция возвращает ссылку на ostream, можно конкатенировать вызовы operator<< следующим образом: