Рейтинговые книги
Читем онлайн Освой самостоятельно С++ за 21 день. - Джесс Либерти

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 94 95 96 97 98 99 100 101 102 ... 170

Что дальше

Последняя неделя начинается с изучения дополнительных возможностей наследования. Затем на занятии 16 вы изучите потоки, а на занятии 17 познакомитесь с одним замечательным дополнением стандартов C++ — пространствами имен. Занятие 18 посвящено анализу основ объектно-ориентированного программирования. В этот день внимание будет сконцентрировано не столько на синтаксисе языка, сколько на изучении концепций объектно-ориентированного программирования. На занятии 19 вы познакомитесь с использованием шаблонов, а на занятии 20 узнаете о методах отслеживания исключительных ситуаций и ошибок. Наконец, на последнем занятии будут раскрыты некоторые хитрости и секреты программирования на C++, что сделает вас настоящим гуру в этой области.

День 15-й. Дополнительные возможности наследования

До настоящего момента вы использовали одиночное и множественное наследование для создания относительно простых связей между классами. Сегодня вы узнаете:

• Что такое вложение и как его использовать

• Что такое делегирование и как его использовать

• Как выполнить один класс внутри другого

• Как использовать закрытое наследование

Вложение

Анализируя примеры, приведенные на предыдущих занятиях, вы, вероятно, заметили, что в классах допускается использование в переменных-членах объектов других классов. В этом случае программисты на C++ говорят, что внешний класс содержит внутренний. Так, класс Employee в качестве переменных-членов может содержать строковые объекты (с именем сотрудника) и объекты с целочисленными значениями (зарплатой и т.д.).

В листинге 15.1 представлен незавершенный, но весьма полезный класс String. Запуск такой программы не приведет к выводу каких-либо результатов, но она потребуется при написании других программ этого занятия.

Листинг 15.1. Класс string 

1: #include <iostream.h>

2: #include <string.h>

3:

4: class String

5: {

6:    public:

7:       // конструкторы

8:       String();

9:       String(const char *const);

10:      String(const String &)

11:      ~String();

12:

13:      // перегруженные операторы

14:      char & operator[](int offset);

15:      char operator[](int offset) const;

16:      String operator+(const String&);

17:      void operator+=(const String&);

18:      String & operator= (const String &);

19:

20:      // Общие методы доступа

21:      int GetLen()const { return itsLen; }

22:      const char * GetString() const { return itsString; }

23:      // статический целочисленный счетчик ConstructorCount;

24:

25:   private:

26:      String (int); // закрытый конструктор

27:      char * itsString;

28:      unsigned short itsLen;

29:

30: };

31:

32: // конструктор класса String пo умолчанию создает строку длиной 0 байт

33: String::String()

34: {

35:    itsString = new char[1];

36:    itsString[0] = '';

37:    itsLen=0;

38:    // cout << "tDefault string constructorn";

39:    // ConstructorCount++;

40: }

41:

42: // закрытый конструктор, используемый только

43: // методами клаcса для создания новой cтроки

44: // указанного размера, заполненной нулями

45: String::String(int len)

46: {

47:    itsString = new ohar[len+1];

48:    for (int i = 0; i<=len; i++)

49:       itsString[i] = '';

50:    itsLen=len;

51:    // cout << "tString(int) constructorn";

52:    // ConstructorCount++;

53: }

54:

55: // Преобразует массив символов в cтроку

56: String::String(const char * oonst 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]='';

63:    // cout << "tString(char*) constructorn";

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] = '';

75:    // cout << "tString(String&) constructorn

76:    // ConstructorCount++;

77: }

78:

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

80: String::~String ()

81: {

82:    delete [] itsString;

83:    itsLen = 0;

84:    // cout << "tString destructorn";

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] = '';

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 itsStnng[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: {

128:    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[j];

135:    temp[totalLen]='';

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; j<rhs.GetLen(); j++, i++)

149:       temp[i] = rhs[i-itsLen];

150:    temp[totalLen]='';

151:    *this = temp;

152: }

153:

154: // int String::ConstructorCount = 0;

Результат:

Нет

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

Статическая переменная-член ConstructorCount объявляется и инициализируется соответственно в строках 23 и 154. Значение этой переменной увеличивается на единицу при вызове любого конструктора класса String. Эти функции также заблокированы и будут использоваться в следующих листингах.

В листинге 15.2 объявляется класс Employee, содержащий три объекта класса String.

Листинг 15.2. Класс Employee

1: #include "String.hpp"

2:

3: class Employee

4: {

5:

6:    public:

7:       Employee();

8:       Employee(char *, char *, char >>, long);

9:       ~Employee();

10:      Employee(const Employee&);

11:      Employee & operator= (const Employee &);

12:

13:      const String & GetFirstName() const

14:         { return itsFirstName; }

15:      const String & GetLastName() const { return itsLastName; }

16:      const String & GetAddress() const { return itsAddress; }

17:      long GetSalary() const { return itsSalary; } 18;

19:      void SetFirstName(const String & fNama)

20:         { itsFirstName = fName; }

21:      void SetLastName(const String & lNama)

22:         { itsLastName = lNamo; }

23:      void SetAddress(const String & address)

24:         { itsAddress = address; }

25:      void SetSalary(long salary) { itsSalary = salary; }

26:   private:

27:      String itsFirstName;

28:      String itsLastName;

29:      String itsAddress;

30:      long itsSalary;

31: };

32:

33: Employee::Employee();

34:    itsFirstName(""),

35:    itsLastName(""),

36:    itsAddress(""),

37:    itsSalary(0)

38: { }

39:

40: Employee::Employee(char * firstName, char * lastName,

41:    char * address, long salary):

42:    itsFirstName(firstName),

43:    itsLastName(lastName),

44:    itsAddress(address),

45:    itsSalary(salary)

46: { }

47:

48: Employee::Employee(const Employee & rhs):

49:    itsFirstName(rhs.GetFirstName()),

50:    itsLastName(rhs,GetLastName()),

51:    itsAddress(rhs,GetAddress()),

52:    itsSalary(rhs.GetSalary())

53: { }

54:

55: Employee::~Employea() { }

56:

57: Employee & Employae::Qperator= (const Employee & rhs)

58: {

59:    if (thls — &rhs)

60:       return *this;

61:

62:    itsFlrstName = rhs.GetFlrstName();

63:    itsLastName = rhs,GetLastName();

64:    itsAddress = rhs,GetAddress();

65:    itsSalary = rhs,GetSalary();

66:

67:    return *thls;

68: }

69:

70: int main()

71: {

72:    Employee Edie("Jane","Doe","1461 Shore Parkway", 20000);

73:    Edie.SetSalary(50000);

74:    String LastName("Levine");

75:    Edie.SetLastName(LastName);

76:    Edie.SetFirstName("Edythe");

77:

78:    cout << "Имя: ";

1 ... 94 95 96 97 98 99 100 101 102 ... 170
На этой странице вы можете бесплатно читать книгу Освой самостоятельно С++ за 21 день. - Джесс Либерти бесплатно.

Оставить комментарий