Читаем Освой самостоятельно С++ за 21 день. полностью

62:    for (int i = 0; i

63:       itsString[i] = cString[i];

64:    itsString[itsLen]='\0';

65:    // cout << "\tString(char*) constructor\n";

66:    // ConstructorCount++;

67: }

68:

69: // конструктор-копировщик

70: String::String (const String & rhs)

71: {

72:    itsLen=rhs.GetLen;

73:    itsString = new char[itsLen+1];

74:    for (int i = 0; i

75:       itsString[i] = rhs[i];

76:    itsString[itsLen] = '\0';

77:    // cout << "\tString(String&) constructor\n";

78:    // ConstructorCount++;

79: }

80:

81: // деструктор, освобождает занятую память

82: String::~String

83: {

84:    delete [] itsString;

85:    itsLen = 0;

86:    // cout << "\tString destructor\n";

87: }

88:

89: // этот оператор освобождает память, а затем

90: // копирует строку и размер

91: String& String::operator=(const String & rhs)

92: {

93:    if (this == &rhs)

94:    return <

95:    delete [] itsString;

96:    itsLen=rhs.GetLen;

97:    itsString = new char[itsLen+1];

98:    for (int i = 0; i

99:    itsString[i] = rhs[i];

100:   itsString[itsLen] = 1\0';

101:   return *this;

102:   // cout << "\tString operator=\n";

103: }

104:

105: // неконстантный оператор индексирования,

106: // возвращает ссылку на символ, который можно

107: // изменить!

108: char & String::operator[](int offset)

109: {

110:    if (offset > itsLen)

111:       return itsString[itsLen-1];

112:    else

113:       return itsString[offset];

114: }

115:

116: // константный оператор индексирования,

117: // используется для константных объектов (см. конструктор-копировщик!)

118: char String::operator[](int offset) const

119: {

120:    if (offset > itsLen)

121:       return itsString[itsLen-1];

122:    else

123:       return itsString[offset];

124: }

125: // создает новый объект String, добавляя

126: // текущий обьект к rhs

127: String String::operator+(const String& rhs)

128: {

129:    int totalLen = itsLen + rhs.GetLen;

130:    String temp(totalLen);

131:    int i, j;

132:    for (i = 0; i

133:       temp[i] = itsString[i];

134:    for (j = 0, i = itsLen; j

135:    temp[i] = rhs[j];

136:    temp[totalLen]='\0';

137:    return temp;

138: }

139:

140: // создает новый объект String

141: // из двух объектов класса String

142: String operator+(const String& lhs, const String& rhs)

143: {

144:    int totalLen = lhs.GetLen + rhs.GetLen;

145:    String temp(totalLen);

146:    int i, j;

147:    for (i = 0; i

148:       temp[i] = lhs[i];

149:    for (j = 0, i = lhs.GetLen;; j

150:       temp[i] = rhs[j];

151:    temp[totalLen]='\0';

152:    return temp;

153: }

154:

155: int main

156: {

157:    String s1("String 0ne ");

158:    String s2("String Two ");

159:    char *c1 = { "C-String 0ne " } ;

160:    String s3;

161:    Stnng s4;

162:    String s5;

163:

164:    cout << "s1: " << s1.GetString << endl;

165:    cout << "s2: " << s2.GetString << endl;

166:    cout << "c1: " << c1 << endl;

167:    s3 = s1 + s2;

168:    cout << "s3: " << s3.GetString << endl;

169:    s4 = s1 + cl;

170:    cout << "s4: " << s4.GetStnng << endl;

171:    s5 = c1 + s2;

172:    cout << "s5: " << s5.GetString << endl;

173:    return 0;

174: }


Результат:

s1: String 0ne

s2: String Two

c1: C-String One

s3: String One String Two

s4: String One C-String One

s5: C-String One String Two


Анализ: Объявления всех методов класса String, за исключением operator+, остались такими же, как в листинге 15.1. В строке 20 листинга 15.8 перегружается новый operator+, который принимает две ссылки на константные строки и возвращает строку, полученную в результате конкатенации исходных строк. Эта функция объявлена как друг класса String.

Обратите внимание, что функция operator+ не является функцией-членом этого или любого другого класса. Она объявляется среди функций-членов класса string как друг, но не как член класса. Тем не менее это все же полноценное объявление функции, и нет необходимости еще раз объявлять в программе прототип этой функции.

Выполнение функции operator+ определяется в строках 142—153. Определение выполнения функции аналогично приведенному в версии программы, представленной в листинге 15.1, за тем исключением что функция принимает в качестве аргументов две строки, обращаясь к ними с помощью открытых методов доступа класса.

Перегруженный оператор применяется в строке 171, где выполняется конкатенация двух строк.


Функции-друзья

Для объявления функции как друга класса используется ключевое слово friend, за которым следует объявление функции Это не предоставляет функции доступ к указателю this, но обеспечивает доступ ко всем закрытым и защищенным данным и функциям-членам.

Пример:

class PartNode

{  // ...

   // сделаем функцию-член другого класса другом этого класса

   friend void PartsList::Insert(Part*)

   // сделаем другом глобальную функцию

   friend int SomeFunction;

   // ...

};

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT