- •Часть 3. Объектно-ориентированное программирование
- •Екатеринбург
- •Введение
- •Классы Описание класса
- •Описание объектов
- •Указатель this
- •Конструкторы
- •Конструктор копирования
- •Конструктор копирования для класса monstr:
- •Статические элементы класса
- •Статические поля
- •Статические методы
- •Дружественные функции и классы Дружественные функции
- •Дружественный класс
- •Деструкторы
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Наследование Ключи доступа
- •Простое наследование
- •Правила наследования методов
- •Виртуальные методы и механизм позднего связывания
- •Абстрактные классы
- •Обработка исключительных ситуаций
- •Синтаксис исключений
- •Перехват исключений
- •Список исключений
- •Иерархии исключений
- •Библиографический список
- •Оглавление
- •Часть 3. Объектно-ориентированное программирование
- •620002, Екатеринбург, ул.Мира, 19
- •620002, Екатеринбург, ул.Мира, 19
Конструктор копирования
Конструктор копирования – это специальный вид конструктора, получающий в качестве единственного параметра указатель на объект этого же класса:
T : : T(const &T) {/*тело конструктора*/}
Здесь T – имя класса.
Этот конструктор вызывается в тех случаях, когда новый объект создается путем копирования существующего:
-
при описании нового объекта с инициализацией другим объектом;
-
передаче объекта в функцию по значению;
-
возврате объекта из функции.
Если программист не указал ни одного конструктора копирования, компилятор создает его автоматически.
Конструктор копирования для класса monstr:
Monstr : : (const monstr &M) {
if (M.name) {
name = new char [strlen (M.name) +1];
strcpy(name, M.name);}
else name = 0;
health =M.health; ammo= M.ammo; skin=M.skin;
}
…
monstr Vasia (blue);
monstr Super = Vasia; // работает конструктор копирования
monstr *m=new monstr (“Ork”);
monstr Green = *m; // работает конструктор копирования
Статические элементы класса
С помощью модификатора static можно описать статические поля и методы класса. Их можно рассматривать как глобальные переменные или функции, доступные только в пределах области класса.
Статические поля
Статические поля применяются для хранения данных, общих для всех объектов класса. Эти поля существуют для всех объектов класса в единственном экземпляре, т.е. не дублируются.
Имеются следующие особенности у статических полей.
-
Память под них выделяется один раз при их инициализации независимо от числа созданных объектов и инициализируются с помощью операции доступа к области действия, а не операции выбора (определение должно быть записано вне функций):
class A {
public:
static int count; // объявление класса
};
…
int A : : count; // определение в глобальной области
// по умолчанию инициализируется нулем
// int A : : count =10; пример инициализации значением 10.
-
Статические поля доступны как через имя класса, так и через имя объекта:
A *a, b;
…
cout << A: :count << a->count <<b.count;
// будет выведено одно и то же
-
На статические поля распространяется действие специфического доступа, поэтому статические поля, описанные как private, нельзя изменить с помощью операции доступа к области действия, как и описано выше. Это можно сделать только с помощью статических методов.
-
Память, занимаемая статическим полем, не учитывается при определении размера объекта с помощью операции sizeof.
Статические методы
Статические методы предназначены для обращения к статическим полям класса. Они могут обращаться непосредственно только к статическим полям и вызывать только другие статические методы класса, потому что им не передается указатель this. Обращение к статическим методам производится так же, как и к статическим полям:
class A {
static int count;
public:
static void inc_count ( ) {count ++;}
…
};
…
A: :int count;
void f ( ) {
A a;
a.inc_count ( ); // A: :inc_count ( );
Статические методы не могут быть константными и виртуальными.
Дружественные функции и классы Дружественные функции
Дружественные функции применяются для доступа к скрытым полям класса и представляют альтернативу методам. Метод, как правило, описывает свойство объекта, а в виде дружественных функций оформляются действия, не являющиеся свойствами класса, но концептуально входящие в его интерфейс и нуждающиеся в доступе к его скрытым полям.
Особенности дружественных функций:
- дружественная функция объявляется внутри класса с ключевым словом friend. В качестве параметра ей должен передаваться объект или ссылка на объект класса, поскольку указатель this ей не передается;
- дружественная функция может быть обычной функцией или методом другого ранее определенного класса. На нее не распространяется действие спецификаторов доступа; место размещения ее объявления в классе безразлично;
- одна функция может быть дружественной сразу нескольким классам.
Пример
class monstr;
class hero {
public:
void rill (monstr &);
…
};
class monstr {
…
friend int steal_ammo (monstr &);
friend void hero: : kill (monstr &);
};
int steal_ammo (monstr &M) { return --ammo;}
void hero: : kill (monstr &M) {M.health=0; M.ammo=0;}
Пояснения
Функция kill является методом класса hero, а функция steal_ammo не принадлежит одному из классу.