Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование_С++_ч_3.doc
Скачиваний:
14
Добавлен:
22.11.2018
Размер:
217.6 Кб
Скачать

Конструктор копирования

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

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 можно описать статические поля и методы класса. Их можно рассматривать как глобальные переменные или функции, доступные только в пределах области класса.

Статические поля

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

Имеются следующие особенности у статических полей.

  1. Память под них выделяется один раз при их инициализации независимо от числа созданных объектов и инициализируются с помощью операции доступа к области действия, а не операции выбора (определение должно быть записано вне функций):

class A {

public:

static int count; // объявление класса

};

int A : : count; // определение в глобальной области

// по умолчанию инициализируется нулем

// int A : : count =10; пример инициализации значением 10.

  1. Статические поля доступны как через имя класса, так и через имя объекта:

A *a, b;

cout << A: :count << a->count <<b.count;

// будет выведено одно и то же

  1. На статические поля распространяется действие специфического доступа, поэтому статические поля, описанные как private, нельзя изменить с помощью операции доступа к области действия, как и описано выше. Это можно сделать только с помощью статических методов.

  2. Память, занимаемая статическим полем, не учитывается при определении размера объекта с помощью операции 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 не принадлежит одному из классу.