main ()
{
int i=7; float d=1,5; long l=36000; cout<<sqrt_it (i); cout<<sqrt_it (d); cout<<sqrt_it (l); unsigned int u=4; cout<<sqrt_it (u);
}
int sqrt_it (int i) { return i*i; }
float sqrt_it (float d)
{return d*d; } long sqrt_it (long l)
{return l*l; }
Перегруженные функции не могут отличаться только типом возвращаемого значения:
int sqrt_it (long i); long sqrt_it (long i); sqrt_it (67000);
При обращении перед компилятором встает неразрешимая проблема: какую из перегруженных функций выбрать?
8.1. Перегрузка конструктора
Перегрузка конструктора класса осуществляется просто объявлением конструкторов с различным набором параметров.
Пример: class date{
int month, day, year; public: date (int, int, int); date (char *);
date (int); date (void);
…
};
21
date begin; date today (23);
date my_day (05,06,2000); date xmas (“02 января”);
В зависимости от того, какие параметры заданы, выбирается соответствующий конструктор.
9. АРГУМЕНТЫ ФУНКЦИИ, ЗАДАВАЕМЫЕ ПО УМОЛЧАНИЮ
Пример:
int fun (int x=1, int y=1){ return x*y; } fun (5,10);
fun (4); //”y”– значение по умолчанию; fun (); // оба значения по умолчанию; fun ( ,2); // выдает сообщение об ошибке.
Все аргументы, задаваемые по умолчанию, должны находиться после аргументов, значение которых не заданы по умолчанию.
При использовании функции с аргументами, заданными по умолчанию, и перегруженных функций одновременно, необходимо следить за корректностью их использования.
date (int a=1); – сообщение об ошибке, так как компилятор не знает, какой выбрать конструктор:
date (void);
или date(my_day);
10. НАСЛЕДОВАНИЕ
Наследование – одна из важных черт языков объектноориентированного программирования. Оно реализуется возможностью объединять один класс с другим во время объявления второго класса. Механизм наследования позволяет определять новые классы на основе уже имеющихся.
Класс, на основе которого создается новый класс, называется базовым (родительским классом), а новый – производным (или наследником). Непосредственно базовым классом называется такой класс, который входит в список базовых классов при определении класса. Любой производный класс может стать базовым для других создаваемых классов, таким образом реализуется иерархия классов и объектов.
22
10.1. Одиночное и множественное наследование
Существует возможность одиночного и множественного наследования. При одиночном наследовании базовым является один класс, а при множественном базовых классов может быть несколько.
Механизм одиночного наследования:
А
В
С
Класс А является непосредственно базовым классом; В наследуется от А, С – от В.
Механизм множественного наследования:
А В
С
Класс С наследуется от базовых классов А и В.
10.2. Управление доступом производных классов
При наследовании важную роль играет статус доступа к компонентам класса. В иерархии класса существуют следующие соглашения о правах доступа к компонентам класса:
–собственные (private) элементы доступны только внутри класса, где они определены;
–защищенные (protected) элементы доступны внутри класса и во всех производных класса;
–общедоступные или открытые (public) компоненты класса видимы из любой точки программы.
Таким образом, для объекта, который обменивается сообщениями с другими объектами и обрабатывает их, доступными являются общедоступныекомпоненты всех объектов программы, защищенные данные и функции,
23
являющиеся представителями базовых классов, а также собственные компоненты объекта.
class X { protected: int i; j;
public: void get_ij (void); void put_ij (void) ;};
class Y: public X { int k;
public: int get_k (void); void make_k (void) ;};
Функции-члены класса Y могут использовать функции get_ij, put_ij класса X, но не могут использовать ij, они недоступны для функций get_k и make_k класса Y.
Можно обеспечить доступ функции-члена класса Y к элементам класса X, описав их как protected. В то же время ij остаются недоступными для остальной части программы.
Доступ наследуется к элементам, объявленным защищенными или общими, и не наследуются для собственных private-элементов. При описании производного класса можно изменить статус доступа наследуемым компонентам класса с помощью модификатора статуса доступа.
Выглядит это следующим образом:
class имя_производного класса: [модификатор] имя базового класса{…}
В качестве модификатора статуса доступа используются ключевые слова protected, private и public. Модификатор доступа может отсутствовать и тогда по умолчанию считается public, если производный класс – структура, и private, если производный класс – класс. Если режим доступа public, то все общие и защищенные элементы базового класса остаются общими и защищенными элементами производного класса. Если режим доступа private, то все общие и защищенные элементы базового класса становятся privateэлементами производного класса. Если режим доступа protected, то общие и защищенные элементы базового класса становятся защищенными элементами в производном классе.
24
Режим доступа без класса |
|
Режим доступа в производном классе |
private |
|
недоступен |
protected |
public |
protected |
public |
|
public |
private |
protected |
недоступен |
protected |
|
protected |
public |
|
protected |
private |
рrivate |
недоступен |
protected |
|
private |
public |
|
public |
Таким образом, в производных классах статус доступа компонентов класса может быть ужесточен.
#include <iostream.h> class X {
protected: int i, j; public: int get_ij (void);
int put_ij (void);}; class Y: public X {
int k;
public: int get_k (void); void make_k (void) ;}; class Z: public Y { public: void f (void) ;}; void X :: get_ij (void)
{
cout <<”Введите 2 числа:”; cin>>i>>j;
}
void X :: put_ij (void)
{
cout <<”i=”<<i<<”j=”<<j;
}
int Y :: get_k (void) {return k ;}
void Y :: make_k (void)
25