Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


ЧТО ТАКОЕ ЗАЩИЩЕННЫЕ ЭЛЕМЕНТЫ



При изучении определений базовых классов вы можете встретить элементы, объявленные как public, private и protected (общие, частные и защищенные). Как вы знаете, производный класс может обращаться к общим элементам базового класса, как будто они определены в производном классе. С другой стороны, производный класс не может обращаться к частным элементам базового класса напрямую. Вместо этого для обращения к таким элементам производный класс должен использовать интерфейсные функции. Защищенные элементы базового класса занимают промежуточное положение между частными и общими. Если элемент является защищенным, объекты производного класса могут обращаться к нему, как будто он является общим. Для оставшейся части вашей программы защищенные элементы являются как бы частными. Единственный способ, с помощью которого ваши программы могут обращаться к защищенным элементам, состоит в использовании интерфейсных функций. Следующее определение класса book использует метку protected, чтобы позволить классам, производным от класса book, обращаться к элементам title, author и pages напрямую, используя оператор точку:

class book { public: book(char *, char *, int); void show_book(void); protected: char title [64]; char author[64]; int pages; };

Если вы предполагаете, что через некоторое время вам придется породить новые классы из создаваемого сейчас класса, установите, должны ли будущие производные классы напрямую обращаться к определенным элементам создаваемого класса, и объявите такие элементы защищенными, а не частными.

Защищенные элементы обеспечивают доступ и защиту Как вы уже знаете, программа не может обратиться напрямую к частным элементам класса. Для обращения к частным элементам программа должна использовать интерфейсные функции, которые управляют доступом к этим элементам. Как вы, вероятно, заметили, наследование упрощает программирование в том случае, если производные классы могут обращаться к элементам базового класса с помощью оператора точки. В таких случаях ваши программы могут использовать защищенные элементы класса. Производный класс может обращаться к защищенным элементам базового класса напрямую, используя оператор точку. Однако оставшаяся часть вашей программы может обращаться к защищенным элементам только с помощью интерфейсных функций этого класса. Таким образом, защищенные элементы класса находятся между общими (доступными всей программе) и частными (доступными только самому классу) элементами.

РАЗРЕШЕНИЕ КОНФЛИКТА ИМЕН

Если вы порождаете один класс из другого, возможны ситуации, когда имя элемента класса в производном классе является таким же, как имя элемента в базовом классе. Если возник такой конфликт, C++ всегда использует элементы производного класса внутри функций производного класса. Например, предположим, что классы book и library_card используют элемент price. В случае класса book элемент price соответствует продажной цене книги, например $22.95. В случае класса library’_card price может включать библиотечную скидку, например $18.50. Если в вашем исходном тексте не указано явно (с помощью оператора глобального разрешения), функции класса library_card будут использовать элементы производного класса {library_card). Если же функциям класса library_card необходимо обращаться к элементу price базового класса {book), они должны использовать имя класса book и оператор разрешения, например book:: price. Предположим, что функции show_card необходимо вывести обе цены. Тогда она должна использовать следующие операторы:

cout < < «Библиотечная цена: $» < < price < < endl; cout < < «Продажная цена: $» < < book:: price < < endl;

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Из этого урока вы узнали, что наследование в C++ позволяет вам строить /порождать) новый класс из существующего класса. Строя таким способом один класс из другого, вы уменьшаете объем программирования, что, в свою очередь, экономит ваше время. Из урока 27 вы узнаете, что C++ позволяет вам порождать класс из двух или нескольких базовых классов. Использование нескольких базовых классов для порождения класса представляет собой множественное наследование. До изучения урока 27 убедитесь, что освоили следующие основные концепции:

1. Наследование представляет собой способность производить новый класс из существующего базового класса.

2. Производный класс — это новый класс, а базовый класс — существующий класс.

3. Когда вы порождаете один класс из другого (базового класса), производный класс наследует элементы базового класса.

4. Для порождения класса из базового начинайте определение производного класса ключевым словом class, за которым следует имя класса, двоеточие и имя базового класса, например class dalmatian: dog.

5. Когда вы порождаете класс из базового класса, производный класс может обращаться к общим элементам базового класса, как будто эти элементы определены внутри самого производного класса. Для доступа к частным данным базового класса производный класс должен использовать интерфейсные функции базового класса.

6. Внутри конструктора производного класса ваша программа должна вызвать конструктор базового класса, указывая двоеточие, имя конструктора базового класса и соответствующие параметры сразу же после заголовка конструктора производного класса.

7. Чтобы обеспечить производным классам прямой доступ к определенным элементам базового класса, в то же время защищая эти элементы от оставшейся части программы, C++ обеспечивает защищенные {protected) элементы класса. Производный класс может обращаться к защищенным элементам базового класса, как будто они являются общими. Однако для оставшейся части программы защищенные элементы эквивалентны частным.

8. Если в производном и базовом классе есть элементы с одинаковым именем, то внутри функций производного класса C++ будет использовать элементы производного класса. Если функциям производного класса необходимо обратиться к элементу базового класса, вы должны использовать оператор глобального разрешения, например base class:: member.

Из урока 26 вы узнали, что можно построить один класс из другого, наследуя его характеристики. Оказывается, C++ позволяет порождать класс из нескольких базовых классов. Когда ваш класс наследует характеристики нескольких классов, вы используете множественное наследование. Как вы узнаете из данного урока, C++ полностью поддерживает множественное наследование. К концу этого урока вы изучите следующие основные концепции:

  • Если вы порождаете класс из нескольких базовых классов, то получаете преимущества множественного наследования.
  • При множественном наследовании производный класс получает атрибуты двух или более классов.
  • При использовании множественного наследования для порождения класса конструктор производного класса должен вызвать конструкторы всех базовых классов.
  • При порождении класса из производного класса вы создаете иерархию наследования (иерархию классов).

Множественное наследование является мощным инструментом объектно-ориентированного программирования. Экспериментируйте с программами, представленными в этом уроке, и вы обнаружите, что построение класса из уже существующего значительно экономит усилия на программирование.

ПРОСТОЙ ПРИМЕР

Предположим, к примеру, у вас есть класс computer_screen:

class computer_screen

{
public:
computer_screen(char *, long, int, int);
void show_screen(void);
private:
char type[32];
long colors;
int x_resolution;
int y_resolution;
};

Предположим, что у вас есть также класс mother_board:

class mother_board

{
public:
mother_board(int, int, int);
void show_mother_board(void);
private:
int processor;
int speed;
int RAM;
};

Используя эти два класса, можно породить класс computer, что показано ниже:

class computer: public computer_screen, public mother_board

{
public:
computer(char *, int, float, char *, long, int, int, int, int, int);
void show_computer(void);
private:
char name[64];
int hard_disk;
float floppy;
};

Как видите, этот класс указывает свои базовые классы сразу после двоеточия, следующего за именем класса computer.

class computer: public computer_screen, public mother_board //——————> Базовые классы

Следующая программа COMPUTER. CPP порождает класс computer, используя базовые классы computer_screen и mother_board:

#include < iostream.h>

#include < string.h>

class computer_screen

{
public:
computer_screen(char *, long, int, int);
void show_screen(void);
private:
char type[32];
long colors;
int x_resolution;
int y_resolution;
};

computer_screen:: computer_screen(char *type, long colors, int x_res, int y_ree)

{
strcpy(computer_screen:: type, type);
computer_screen:: colors = colors;
computer_screen:: x_resolution = x_res;
computer_screen:: y_resolution = y_res;
}

void computer_screen:: show_screen(void)

{
cout < < «Тип экрана: » < < type < < endl;
cout < < «Цветов: » < < colors < < endl;
cout < < «Разрешение: » < < x_resolution < < » на » < < y_resolution < < endl;
}

class mother_board

{
public:
mother_board(int, int, int);
void show_mother_board(void);
private:
int processor;
int speed;
int RAM;
};

mother_board:: mother_board(int processor, int speed, int RAM)

{
mother_board:: processor = processor;
mother_board:: speed = speed;
mother_board:: RAM = ram;
}

void mother_board:: show_mother_board(void)

{
cout < < «Процессор: » < < processor < < endl;
cout < < «Частота: » < < speed < < «МГц» < < endl;
cout < < «ОЗУ: » < < RAM < < » МВайт» < < endl;
}

class computer: public computer_screen, public mother_board

{
public:
computer(char *, int, float, char *, long, int, int, int, int, int);
void show_computerf void);
private:
char name [64];
int hard_disk;
float floppy;
};

computer:: computer(char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM): computer_screen(screen, colors, x_res, y_res), mother_board(processor, speed, ram)

{
strcpy(computer:: name, name);
computer:: hard_disk = hard_disk;
computer:: floppy = floppy;
}

void computer:: show_computer(void)

{
cout < < «Тип: » < < name < < endl;
cout < < «Жесткий диск: » < < hard_disk < < «МВайт» < < endl;
cout < < «Гибкий диск: » < < floppy < < «МВайт» < < endl;
show_mother_board();
show_screen();
}

void main(void)

{
computer my_pc(«Compaq», 212, 1.44, «SVGA», 16000000, 640, 480, 486, 66, 8);
my_pc.show_computer();
}

Если вы проанализируете конструктор класса computer, то обнаружите, что он вызывает конструкторы классов mother_board и computer_screen, как показано ниже:

computer:: computer(char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM): computer_screen(screen, colors, x_res, y_res), mother_board(processor, speed, RAM)

ПОСТРОЕНИЕ ИЕРАРХИИ КЛАССОВ

При использовании наследования в C++ для порождения одного класса из другого возможны ситуации, когда вы порождаете свой класс из класса, который уже, в свою очередь, является производным от некоторого базового класса. Например, предположим, вам необходимо использовать класс сотputer базовый для порождения класса workstation, как показано ниже:

class work_station: public computer

{
public:
work_station (char *operating_system, char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM);
void show_work_station(void);
private:
char operating_system[64];
};

Конструктор класса workstation просто вызывает конструктор класса computer, который в свою очередь вызывает конструкторы классов сотрuter_screen и mother_board:

work_station:: work_station( char *operating_system, char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM): computer (name, hard_disk, floppy, screen, colors, x_res, y_res, processor, speed, RAM)

{
strcpy(work_station:: operating_system, operating_system);
}

В данном случае класс computer выступает в роли базового класса. Однако вы знаете, что класс computer был порожден из классов computer_screen и mother_board. В результате класс work_station наследует характеристики всех трех классов. На рис. 27 показано, что порождение классов приводит к иерархии классов.

Рис. 27. Построение иерархии классов.

Когда ваши программы будут интенсивно использовать наследование, ваша иерархия классов, а следовательно, и количество наследуемых элементов может стать довольно длинной.

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

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

1. Множественное наследование является способностью порожденного класса наследовать характеристики нескольких базовых классов.

2. Для порождения класса из нескольких базовых после имени нового класса и двоеточия вы указываете имена базовых классов, разделяя их запятыми, например class cabbit: public cat, public rabbit.

3. При определении конструктора производного класса вы должны вызвать конструкторы всех базовых классов, передавая им необходимые параметры.

4. При порождении классов может случиться так, что используемый вами базовый класс реально порожден из других базовых классов. Если так, то ваша программа создает иерархию классов. Если вызывается конструктор вашего производного класса, то вызываются также и конструкторы наследуемых классов (последовательно).

Как вы уже знаете, ваши программы могут обращаться к частным (private) элементам класса только с помощью функций-элементов этого же класса. Используя частные элементы класса вместо общих во всех ситуациях, где это только возможно, вы уменьшаете возможность программы испортить значения элементов класса, так как программа может обращаться к таким элементам только через интерфейсные функции (которые управляют доступом к частным элементам). Однако в зависимости от использования объектов вашей программы, иногда вы можете существенно увеличить производительность позволяя одному классу напрямую обращаться к частным элементам другого. В этом случае уменьшаются издержки (требуемое время выполнения) на вызов интерфейсных функций. В подобных ситуациях C++ позволяет определить класс в качестве друга (friend} другого класса и разрешает классу-другу доступ к частным элементам этого другого класса. В этом уроке объясняется, как ваши программы могут указать, что два класса являются друзьями. К концу данного урока вы освоите следующие основные концепции:

  • Используя ключевое слово friend, класс может сообщить C++, кто является его другом, т. е. другими словами, что другие классы могут обращаться напрямую к его частным элементам.
  • Частные элементы класса защищают данные класса, следовательно, вы должны ограничить круг классов-друзей только теми классами, которым действительно необходим прямой доступ к частным элементам искомого класса.
  • C++ позволяет ограничить дружественный доступ определенным набором функций.

Частные (private) элементы позволяют вам защищать классы и уменьшить вероятность ошибок. Таким образом, вы должны ограничить использование классов-друзей настолько, насколько это возможно. Иногда программа напрямую может изменить значения элементов класса, это увеличивает вероятность появления ошибок.

ОПРЕДЕЛЕНИЕ ДРУЗЕЙ КЛАССА

C++ позволяет друзьям определенного класса обращаться к частным элементам этого класса. Чтобы указать C++, что один класс является другом (friend) другого класса, вы просто помещаете ключевое слово friend и имя соответствующего класса-друга внутрь определения этого другого класса. Например, приведенный ниже класс book объявляет класс librarian своим другом. Поэтому объекты класса librarian могут напрямую обращаться к частным элементам класса book, используя оператор точку:

 

class book

{
public:
book (char *, char *, char *);
void show_book(void);
friend librarian;
private:
char title [64];
char author[64];
char catalog[64];
};

Как видите, чтобы указать друга, необходим только один оператор внутри определения класса. Например, следующая программа VIEWBOOK.CPP использует librarian в качестве друга класса book. Следовательно, функции класса librarian могут напрямую обращаться к частным элементам класса book. В данном случае программа использует функцию change_catalog класса librarian для изменения номера карточки каталогаопределенной книги:

#include < iostream.h>

#include < string.h>

class book

{
public:
book (char *, char *, char *);
void show_book(void);
friend librarian;
private:
char title[64];
char author[64];
char catalog[64];
};

book:: book(char *title, char *author, char •catalog)

{
strcpy(book:: title, title);
strcpy(book:: author, author);
strcpy(book:: catalog, catalog);
}

void book:: show_book(void)

{
cout < < «Название: » < < title < < endl;
cout < < «Автор: » < < author < < endl;
cout < < «Каталог: » < < catalog < < endl;
}

class librarian

{
public:
void change_catalog(book *, char *);
char *get_catalog(book);
};

void librarian:: change_catalog(book *this_book, char *new_catalog)

{
strcpy(this_book-> catalog, new_catalog);
}

char *librarian: : get__catalog(book this_book)

{
static char catalog[64];
strcpy(catalog, this_book.catalog);
return(catalog);
}

void main(void)

{
book programming( «Учимся программировать на языке C++», «Jamsa», «P101″ );
librarian library;
programming.show_book();
library.change_catalog(& programming, «Легкий C++ 101″ );
programming.show_book();
}

Как видите, программа передает объект book в функцию change_catalog класса librarian по адресу. Поскольку эта функция изменяет элемент класса book, программа должна передать параметр по адресу, а затем использовать указатель для обращения к элементу этого класса. Экспериментируйте с данной программой, попробуйте удалить оператор friend из определения класса book. Поскольку класс librarian больше не имеет доступа к частным элементам класса book, компилятор C++ сообщает о синтаксических ошибках при каждой ссылке на частные данные класса book.

О друзьях класса

Обычно единственный способ, с помощью которого ваши программы могут обращаться к частным элементам класса, заключается в использовании интерфейсных функций. В зависимости от использования объектов программы иногда может быть удобным (или более эффективным с точки зрения скорости вычислений) разрешить одному классу обращаться к частным элементам другого. Для этого вы должны информировать компилятор C++, что класс является другом (friend). Компилятор, в свою очередь, позволит классу-другу обращаться к частным элементам требуемого класса. Чтобы объявить класс другом, поместите ключевое слово friend и имя класса-друга в секцию public определения класса, как показано ниже:

Class abbott

{
public:
friend costello;
// Общие элементы
private:
// Частные элементы
};

Как друзья отличаются от защищенных (protected) элементов

Из урока 26 вы узнали, что в C++ существуют защищенные (protected) элементы класса, что позволяет производным классам обращаться к защищенным элементам базового класса напрямую, используя оператор точку. Помните, что к защищенным элементам класса могут обращаться только те классы, которые являются производными от данного базового класса, другими словами, классы, которые наследуют элементы базового класса (защищенные элементы класса являются как бы частными по отношению к остальным частям программы). Классы-друзья C++ обычно не связаны между собой узами наследования. Единственный способ для таких не связанных между собой классов получить доступ к частным элементам другого класса состоит в том, чтобы этот другой класс информировал компилятор, что данный класс является другом.


Поделиться:



Популярное:

  1. B. Ключевые элементы в учении амилленаризма
  2. Bizz: Допустим, клиент не проверил карман, а там что-то лежит, что может повредит аппарат. Как быть в такой ситуации?
  3. Cтадии развития организации, виды оргструктур, элементы организационной структуры
  4. I - Что относится к внешним проявлениям дружбы с неверными.
  5. I LEARN THAT I AM ON AN ISLAND (я узнаю, что я на острове)
  6. I SEE SOMETHING IN THE SAND (я вижу кое-что в песке)
  7. I. Чтобы они поистине были универсальными для научных занятий.
  8. III. Зрелые форменные элементы класса VI
  9. XVII. ЧТО РАЗРУШАЕТ ПСИХИЧЕСКУЮ ЭНЕРГИЮ?
  10. А если хочешь узнать что у тебя за команда, достаточно сыграть с сильным противником. Ты сразу удивишь все недостатки и недоработки, узнаешь, кто из игроков что стоит.
  11. А может, сделать так, чтобы и у детей всего мира – у белых, черных, желтых – тоже было знамя одного цвета?
  12. А почему происходит то, что «происходит»?


Последнее изменение этой страницы: 2016-05-30; Просмотров: 601; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.043 с.)
Главная | Случайная страница | Обратная связь