|
Программирование >> Дополнительные возможности наследования
ствуют друг с другом и открытие доступа одного класса к данным и методам другого класса существенно упрощает код профаммы. Однако зачастую проще организовать взаимодействие между классами с помощью открытых методов доступа. примечание От начинающих программистов С++ часто можно услышать замечание, что объявление классов-друзей противоречит принципу инкапсуляции, лежащему в основе объектно-ориентированного программирования. Это, честно говоря, довольно широко распространенная бессмыслица. Объявление класса-друга просто расширяет интерфейс другого класса, что влияет на инкапсуляцию не больше, чем открытое наследование классов. Дружественный класс Объявление одного класса другом какого-либо иного с помощью ключевого слова friend в объявлении второго класса открывает первому классу доступ к членам второго класса. Иными словами, я могу объявить вас своим другом, но вы не можете объявить себя моим другом. Пример: ь;,:p(iblieH:j;?-:* ;;-:- у/уу: уЯ - и :Уух: MxP ~W ; :::г1е Шункции-друзья Иногда бывает необходимо предоставить права доступа не всему классу, а только одной или нескольким функциям-членам. Это реализуется посредством объявления друзьями функций-членов другого класса. Причем объявлять другом весь класс вовсе не обязательно. Фактически другом можно объявить любую функцию, независимо от того, является ли она функцией-членом другого класса или нет. Шункции-друзья и перегрузка оператора в листинге 15.1 представлен класс String, в котором перегружается operator+. В нем также объявляется конструктор, принимающий указатель на константную строку, поэтому объект класса String можно создавать из строки с концевым нулевым символом. нримечанне Строки в С и С++ представляют собой массивы символов, заканчивающиеся концевым нулевым символом. Такая строка получается, например, в следующем выражении присвоения: myString[ ] = Hello World . Но чего невозможно сделать в классе string, так это получить новую строку в результате сложения объекта этого класса с массивом символов: char cString[] = { Hello } ; String sString( World ): String sStringTwo = cString + sString; ошибка! Строки нельзя использовать с перефуженной функции operator+. Как объяснялось на занятии 10, выражение cString + sString на самом деле вызывает функцию cString.operator+(sString). Поскольку функция operator+() не может вызываться для символьной строки, данная попытка приведет к ошибке компиляции. Эту проблему можно решить, объявив функцию-друга в классе String, которая пе-рефужает operator+ таким образом, чтобы суммировать два объекта string. Соответствующий конструктор класса string преобразует строки в объекты String, после чего вызывается функция-друг operator+, выполняющая конкатенацию двух объектов. Аисшинг 15.8. Функцня-уруг operateг+ 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Листинг 15.8. Операторы друзья Sinclude <iostream.h> Sinclude <string.h> Рудиментарный класс string class String public: constructors StringO; String(const char *const); String(const String &); StringO; перегруженные операторы char & operator[](int offset); char operator[](int offset) const; String operator+(const String&); friend String operator+(const Strings const String*); void operator+=(const String&); String & operator= (const String &); методы общего доступа int GetLen( )const { return itsLen; } const char ♦ GetStringO const { return itsString; } private: String (int); закрытый конструктор char * itsString; unsigned short itsLen; 34: конструктор, заданный по умолчанию, создает строку длиной О байт 35; String::String() 36; { 37: itsString = new char[1]; 38; itsString[0] = \ 0; 39: itsLen=0; 40: cout << X tDefault string constructor\ n ; 41: ConstructorCount++; 42: } 43: 44: закрытый конструктор, используемый только 45: методами класса для создания новой строки 46: указанного размера, заполненной нулями. 47: String;:String(int len) 48: { 49: itsString = new char[len+1]; 50: for (int i = 0; i<=len; i++) 51: itsString[i] = \ 0 ; 52; itsLen=len; 53: cout \ tString(int) constructor\ n ; 54: ConstructorCount++; 55: } 56: 57: Преобразует массив символов в строку 58: String::String(const char * const cString) 59: { 60: itsLen = strlen(cString); 61: itsString = new char[itsLen+1]; 62: for (int i = 0; i<itsLen; i++) 63: itsString[i] = cString[i]; 64; itsString[itsLen]=\ 0; 65: cout X tString(char*) constructor\ n ; 66: ConstructorCount++; 67: I 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<itsLen;i++) 75: itsString[i] = rhs[i]; 76: itsString[itsLen] = \ 0 ; 77; cout X tString(String&) constructor\ n ; 78: ConstructorCount++: 79; } 80: 81; деструктор, освобождает занятую память 82: String::String () 83: {
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |