Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МВ_Прог_1курс_2n1часть.doc
Скачиваний:
12
Добавлен:
13.04.2015
Размер:
736 Кб
Скачать
☆
    1. Уровни доступа

Любой элемент класса имеет один из трех уровней доступа:

  • private (закрытый) – доступен только из функций-членов данного класса и дружественных функций;

  • protected (защищенный) – доступен как private, а также из функций-членов производных классов;

  • public (открытый) – доступен всюду, где виден класс.

В объявлении класса обычно сначала перечисляются все открытые элементы, потом защищенные, потом закрытые.

В заголовке производного класса указываются имена всех базовых классов вместе со спецификаторами доступа.

class Derived: сп_доступа Base1 [, сп_доступа Base2,...] {...};

Замечание. Базовых классов больше одного, если наследование множественное.

Спецификаторы определяют уровень доступа к элементам базового класса внутри производного. Уровень доступа к элементу определяется как меньший из двух - того, что элемент имеет внутри базового класса и того, что указан в производном классе (private < protected < public).

Явное указание спецификатора доступа при наследовании не обязательно. По умолчанию принимается private для базовых классов и public для базовых структур и объединений.

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

Пример. Возврат утраченного статуса.

class Base {

public:

void f1();

};

class Derived: private Base {

public:

Base::f1; // делает f1() снова публичным

};

Если элемент описан в базовом классе как private, его никак нельзя сделать public в производном классе.

    1. Виртуальные функции

Виртуальные функции позволяют уже в базовом классе вызывать функции, которые будут определены позже в производных классах.

Пример. Класс с виртуальными функциями.

Определим базовый класс date

class date {

protected:

int day, month, year;

public:

date(int,int,int);

void set_year(int y);

void print();

};

date::date(int d, int m, int y)

{

day = d; month = m; year = y;

}

void date::set_year(int y)

{

year = y;

print();

}

void date::print()

{

printf("%d-%d-%d\n", day, month, year);

}

и производный от него класс birthday:

class birthday: public date {

public:

char name[80];

birthday(int d, int m, int y, char* n);

void print();

};

birthday::birthday(int d, int m, int y, char* n) : date(d, m, y)

{

strcpy(name, n);

}

void birthday::print()

{

printf("%d-%d-%d, dear %s\n", day, month, year, name);

}

Следующий код

date* d = new date(19, 10, 1951);

birthday* b = new birthday(19, 10, 1951, "Bond");

d->set_year(2001);

b->set_year(2001);

напечатает: "19-10-1951" два раза.

Если же сделать метод date::print() виртуальным,

virtual void print(int y);

то тот же код напечатает:

"19-10-1951"

"19-10-1951, dear Bond".

Чтобы сделать метод виртуальным, достаточно объявить его с описателем virtual.

Для виртуальных функций действуют следующие правила:

  1. виртуальную функцию нельзя объявлять как static; .

  2. спецификатор virtual писать не обязательно при переопределении функции в производном классе, переопределенная функция все равно будет виртуальной.

  3. виртуальная функция должна быть определена в классе, где она впервые объявлена или должна быть чисто виртуальной, т.е. не иметь кода.

virtual void print() = 0;

Класс, содержащий чисто виртуальные функции, является абстрактным, объекты такого класса не могут быть созданы. Единственным назначением абстрактных классов является “вынесение за скобки” общих свойств их потомков и обеспечение полиморфизма.