Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

pragma once Hard / Занятие 1

.doc
Скачиваний:
14
Добавлен:
13.03.2015
Размер:
52.74 Кб
Скачать

Понятие класса. Создание простейших классов. Конструкторы и деструкторы

Понятие класса

Набор данных в сочетании с совокупностью операций над ними называется абстрактным типом данных (abstract data type), или АТД. Класс – абстрактный тип данных, определяемый пользователем.

Операции над данными в классах представляются в виде функций. Данные-члены (data members) часто называют полями, а функции-члены (member function) – методами. Поля и методы называются элементами класса.

class имя_класса {

данные-члены класса;

функции-члены класса;

} [список_объектов];

Если список_объектов отсутствует, то объекты объявляются в программе по мере необходимости.

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

class имя_класса {

[private:]

описание скрытых элементов

public:

описание открытых элементов

} ;

Все методы класса имеют доступ ко всем членам класса, в том числе и к закрытым.

Действие любого спецификатора (public, private) распространяется до следующего спецификатора или до конца класса. По умолчанию – private. Можно задавать несколько секций private и publiс.

Пример 1.1. Пример простейшего класса.

#include <iostream>

using namespace std;

class point {

public:

int x, y;

void print_point () {

cout <<'('<<x<<','<<y<<')'<<endl;

}

};

void Prim1_1() {

point a;

a.x=2; a.y=7;

a.print_point();

point b[3];

for (int i=0; i<3; i++){

b[i].x=i; b[i].y=i+2; b[i].print_point();

}

}

int main() {

Prim1_1();

}

Задание. Объясните разницу между структурой и классом:

struct x (

int i, j, k;

};

class x (

int i, j, k;

};

Поля могут иметь любой тип, кроме типа этого же класса (но могут быть указателями или ссылками на этот же класс).

Инициализация полей при описании не допускается. В каждом классе есть хотя бы один метод, имя которого совпадает с именем класса (конструктор). Он вызывается автоматически при создании объекта класса и предназначен для инициализации объекта.

Тип возвращаемого значения в определении конструктора не указывается.

Методы класса могут быть как определены в классе, так и объявлены (приведены только заголовки).

Если тело метода определено внутри класса, он является встроенным.

Если метод только объявлен внутри класса, то его нужно определить в другом месте программы с помощью операции доступа к области видимости «::»:

тип имя_класса::имя_метода (параметры) {

/* тело метода */ }

Чтобы создать объект (экземпляр класса) нужно объявить в программе переменную типа «класс».

Каждый объект имеет собственные копии полей, но методы у них общие.

Если поле описано как статическое (static), то оно существует в единственном экземпляре (общее для всех объектов класса).

Статические методы предназначены для обращения к статическим полям. Они могут обращаться только к статическим полям и вызывать другие статические методы класса.

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

class point {

public:

int x, y; //поля

void print_point () { //метод

cout <<'('<<x<<','<<y<<')'<<endl;

}

point(){x=1; y=1;}//конструктор по умолчанию

//объявление конструктора с параметрами

point(int x1,int y1){x=x1; y=y1;}

void move(int dx, int dy); //объявление метода

};

void point::move(int dx, int dy){x+=dx; y+=dy;} //определение метода

void Prim1_1() {

point a; a.print_point();

a.x=2; a.y=7;

a.print_point();

point b[3];

for (int i=0; i<3; i++){

b[i].x=i; b[i].y=i+2; b[i].print_point();

}

point c(-5,2); c.print_point();

c.move(5,5); c.print_point();

}

Пример 1.2.

class rectangle{

public:

point top_left;

point bottom_right;

int perim() {return 2*(bottom_right.x - top_left.x)+

2*(bottom_right.y - top_left.y); }; };

int main(){

rectangle r;

r.top_left.x=0; r.top_left.y=0;

r.bottom_right.x=100; r.bottom_right.y=50;

cout<< "P=" << r.perim() << endl;

return 0; }

Конструктор – это функция-элемент класса, автоматически выполняющаяся в момент создания объекта.

Имя конструктора совпадает с именем класса. Конструкторы можно перегружать.

Свойства конструктора:

  • не указывается тип возвращаемого значения;

  • не может возвращать значение;

  • не наследуется.

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

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

Деструктор – это функция-элемент класса, автоматически выполняющаяся при удалении объекта (функция, обратная конструктору). Деструктор не уничтожает объект, а только выполняет подготовительные действия.

Имя деструктора совпадает с именем класса, но имеет префикс «~» (тильда).

Деструктор не имеет аргументов и не может возвращать значение, поэтому в классе он всегда один.

Если деструктор не объявлен явно, он создается компилятором как пустая функция.

Один объект можно присвоить другому, если они одинакового типа.

Когда один объект А присваивается объекту В, происходит побитовое копирование всех данных-элементов А в данные-элементы В. Данные-элементы объектов А и В приобретают одинаковые значения, при этом объекты остаются совершенно независимыми.

Присваивать можно только объекты одного типа (т.е. с одним именем типа), а не типов одинаковых физически.

Например, в предыдущем примере можно написать:

a=b;

Конструктор копирования используется при инициализации объекта существующим объектом.

Инициализация имеет место в трех случаях:

  • когда в операторе объявления один объект используется для инициализации другого: MyClass O1=O2;

  • при передаче объекта в качестве параметра функции: f1(O1);

  • при создании временного объекта для возврата значения из функции:

O2 = f2().

Конструктор копирования никогда не используется при присваивании.

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

Если в классе есть динамический массив, то копируется только указатель, а не элементы. После выполнения delete второй указатель будет не определен.

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

имя_класса (const имя_класса &obj)

{ тело_конструктора}

где obj – ссылка на объект, используемый для инициализации другого объекта.

Пример 1.3. Пример класса, содержащего динамический массив

#include <iostream>

using namespace std;

#include <iomanip>

class array { int *arr; int n;

public: array(int m){arr = new int[m]; n=m;} //конструктор

array (const array &a); //прототип конструктора копирования

~array() {delete []arr;} //деструктор

void put(int i, int v) {if (i>=0 && i<n) arr[i]=v; }

int get(int i) {return arr[i];} };

array::array(const array &a) { int i;

arr = new int [a.n]; //выделение памяти для копии массива

for (i=0; i<a.n; i++) arr[i]=a.arr[i]; } //копирование содержимого

void main (){ int i; array x(5); //вызов обычного конструктора

for (i=0; i<5; i++) x.put(i,i);

array y=x; //вызов конструктора копирования

for (i=0; i<5; i++) cout << setw(3) << y.get(i); }

Задание: создайте класс «прямоугольник» с полями «высота» и «ширина» и методами «площадь» и «периметр». В классе должны быть 2 конструктора: с параметрами для инициализации полей и по умолчанию (инициализация полей единицами).

6

Соседние файлы в папке pragma once Hard